Sam Ravnborg <sam@mars.ravnborg.org>
Sascha Hauer <s.hauer@pengutronix.de>
S.Çağlar Onur <caglar@pardus.org.tr>
+Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com>
Simon Kelley <simon@thekelleys.org.uk>
Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
Stephen Hemminger <shemminger@osdl.org>
What: /sys/bus/iio/devices/iio:deviceX/in_tempX_raw
What: /sys/bus/iio/devices/iio:deviceX/in_temp_x_raw
What: /sys/bus/iio/devices/iio:deviceX/in_temp_y_raw
-What: /sys/bus/iio/devices/iio:deviceX/in_temp_z_raw
+What: /sys/bus/iio/devices/iio:deviceX/in_temp_ambient_raw
+What: /sys/bus/iio/devices/iio:deviceX/in_temp_object_raw
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
Raw (unscaled no bias removal etc.) temperature measurement.
If an axis is specified it generally means that the temperature
sensor is associated with one part of a compound device (e.g.
- a gyroscope axis). Units after application of scale and offset
+ a gyroscope axis). The ambient and object modifiers distinguish
+ between ambient (reference) and distant temperature for contact-
+ less measurements. Units after application of scale and offset
are milli degrees Celsius.
What: /sys/bus/iio/devices/iio:deviceX/in_tempX_input
Description:
Scaled humidity measurement in milli percent.
+What: /sys/bus/iio/devices/iio:deviceX/in_X_mean_raw
+KernelVersion: 3.5
+Contact: linux-iio@vger.kernel.org
+Description:
+ Averaged raw measurement from channel X. The number of values
+ used for averaging is device specific. The converting rules for
+ normal raw values also applies to the averaged raw values.
+
What: /sys/bus/iio/devices/iio:deviceX/in_accel_offset
What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_offset
What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_offset
What: /sys/.../iio:deviceX/scan_elements/in_incli_y_en
What: /sys/.../iio:deviceX/scan_elements/in_pressureY_en
What: /sys/.../iio:deviceX/scan_elements/in_pressure_en
+What: /sys/.../iio:deviceX/scan_elements/in_rot_quaternion_en
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
What: /sys/.../iio:deviceX/scan_elements/in_timestamp_type
What: /sys/.../iio:deviceX/scan_elements/in_pressureY_type
What: /sys/.../iio:deviceX/scan_elements/in_pressure_type
+What: /sys/.../iio:deviceX/scan_elements/in_rot_quaternion_type
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
What: /sys/.../iio:deviceX/scan_elements/in_timestamp_index
What: /sys/.../iio:deviceX/scan_elements/in_pressureY_index
What: /sys/.../iio:deviceX/scan_elements/in_pressure_index
+What: /sys/.../iio:deviceX/scan_elements/in_rot_quaternion_index
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
on-chip EEPROM. After power-up or chip reset the device will
automatically load the saved configuration.
+What: /sys/.../iio:deviceX/in_illuminanceY_input
+What: /sys/.../iio:deviceX/in_illuminanceY_raw
+What: /sys/.../iio:deviceX/in_illuminanceY_mean_raw
+KernelVersion: 3.4
+Contact: linux-iio@vger.kernel.org
+Description:
+ Illuminance measurement, units after application of scale
+ and offset are lux.
+
+What: /sys/.../iio:deviceX/in_intensityY_raw
+What: /sys/.../iio:deviceX/in_intensityY_ir_raw
+What: /sys/.../iio:deviceX/in_intensityY_both_raw
+KernelVersion: 3.4
+Contact: linux-iio@vger.kernel.org
+Description:
+ Unit-less light intensity. Modifiers both and ir indicate
+ that measurements contains visible and infrared light
+ components or just infrared light, respectively.
+
What: /sys/.../iio:deviceX/in_intensity_red_integration_time
What: /sys/.../iio:deviceX/in_intensity_green_integration_time
What: /sys/.../iio:deviceX/in_intensity_blue_integration_time
Description:
This attribute is used to get/set the integration time in
seconds.
+
+What: /sys/bus/iio/devices/iio:deviceX/in_rot_quaternion_raw
+KernelVersion: 3.15
+Contact: linux-iio@vger.kernel.org
+Description:
+ Raw value of quaternion components using a format
+ x y z w. Here x, y, and z component represents the axis about
+ which a rotation will occur and w component represents the
+ amount of rotation.
--- /dev/null
+What /sys/bus/iio/devices/iio:deviceX/in_proximity_raw
+Date: March 2014
+KernelVersion: 3.15
+Contact: Matt Ranostay <mranostay@gmail.com>
+Description:
+ Get the current distance in meters of storm (1km steps)
+ 1000-40000 = distance in meters
+
+What /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity
+Date: March 2014
+KernelVersion: 3.15
+Contact: Matt Ranostay <mranostay@gmail.com>
+Description:
+ Show or set the gain boost of the amp, from 0-31 range.
+ 18 = indoors (default)
+ 14 = outdoors
</para>
<sect1><title>Frame Buffer Memory</title>
-!Edrivers/video/fbmem.c
+!Edrivers/video/fbdev/core/fbmem.c
</sect1>
<!--
<sect1><title>Frame Buffer Console</title>
</sect1>
-->
<sect1><title>Frame Buffer Colormap</title>
-!Edrivers/video/fbcmap.c
+!Edrivers/video/fbdev/core/fbcmap.c
</sect1>
<!-- FIXME:
drivers/video/fbgen.c has no docs, which stuffs up the sgml. Comment
</sect1>
KAO -->
<sect1><title>Frame Buffer Video Mode Database</title>
-!Idrivers/video/modedb.c
-!Edrivers/video/modedb.c
+!Idrivers/video/fbdev/core/modedb.c
+!Edrivers/video/fbdev/core/modedb.c
</sect1>
<sect1><title>Frame Buffer Macintosh Video Mode Database</title>
-!Edrivers/video/macmodes.c
+!Edrivers/video/fbdev/macmodes.c
</sect1>
<sect1><title>Frame Buffer Fonts</title>
<para>
<sect2>
<title>Modeset Helper Functions Reference</title>
!Edrivers/gpu/drm/drm_crtc_helper.c
+ </sect2>
+ <sect2>
+ <title>Output Probing Helper Functions Reference</title>
+!Pdrivers/gpu/drm/drm_probe_helper.c output probing helper overview
+!Edrivers/gpu/drm/drm_probe_helper.c
</sect2>
<sect2>
<title>fbdev Helper Functions Reference</title>
--- /dev/null
+Marvell Kirkwood SoC Family Device Tree Bindings
+------------------------------------------------
+
+Boards with a SoC of the Marvell Kirkwook family, eg 88f6281
+
+* Required root node properties:
+compatible: must contain "marvell,kirkwood"
+
+In addition, the above compatible shall be extended with the specific
+SoC. Currently known SoC compatibles are:
+
+"marvell,kirkwood-88f6192"
+"marvell,kirkwood-88f6281"
+"marvell,kirkwood-88f6282"
+"marvell,kirkwood-88f6283"
+"marvell,kirkwood-88f6702"
+"marvell,kirkwood-98DX4122"
+
+And in addition, the compatible shall be extended with the specific
+board. Currently known boards are:
+
+"buffalo,lschlv2"
+"buffalo,lsxhl"
+"buffalo,lsxl"
+"dlink,dns-320"
+"dlink,dns-320-a1"
+"dlink,dns-325"
+"dlink,dns-325-a1"
+"dlink,dns-kirkwood"
+"excito,b3"
+"globalscale,dreamplug-003-ds2001"
+"globalscale,guruplug"
+"globalscale,guruplug-server-plus"
+"globalscale,sheevaplug"
+"globalscale,sheevaplug"
+"globalscale,sheevaplug-esata"
+"globalscale,sheevaplug-esata-rev13"
+"iom,iconnect"
+"iom,iconnect-1.1"
+"iom,ix2-200"
+"keymile,km_kirkwood"
+"lacie,cloudbox"
+"lacie,inetspace_v2"
+"lacie,laplug"
+"lacie,netspace_lite_v2"
+"lacie,netspace_max_v2"
+"lacie,netspace_mini_v2"
+"lacie,netspace_v2"
+"marvell,db-88f6281-bp"
+"marvell,db-88f6282-bp"
+"marvell,mv88f6281gtw-ge"
+"marvell,rd88f6281"
+"marvell,rd88f6281"
+"marvell,rd88f6281-a0"
+"marvell,rd88f6281-a1"
+"mpl,cec4"
+"mpl,cec4-10"
+"netgear,readynas"
+"netgear,readynas"
+"netgear,readynas-duo-v2"
+"netgear,readynas-nv+-v2"
+"plathome,openblocks-a6"
+"plathome,openblocks-a7"
+"raidsonic,ib-nas6210"
+"raidsonic,ib-nas6210-b"
+"raidsonic,ib-nas6220"
+"raidsonic,ib-nas6220-b"
+"raidsonic,ib-nas62x0"
+"seagate,dockstar"
+"seagate,goflexnet"
+"synology,ds109"
+"synology,ds110jv10"
+"synology,ds110jv20"
+"synology,ds110jv30"
+"synology,ds111"
+"synology,ds209"
+"synology,ds210jv10"
+"synology,ds210jv20"
+"synology,ds212"
+"synology,ds212jv10"
+"synology,ds212jv20"
+"synology,ds212pv10"
+"synology,ds409"
+"synology,ds409slim"
+"synology,ds410j"
+"synology,ds411"
+"synology,ds411j"
+"synology,ds411slim"
+"synology,ds413jv10"
+"synology,rs212"
+"synology,rs409"
+"synology,rs411"
+"synology,rs812"
+"usi,topkick"
+"usi,topkick-1281P2"
+"zyxel,nsa310"
+"zyxel,nsa310a"
ad,adm9240 ADM9240: Complete System Hardware Monitor for uProcessor-Based Systems
adi,adt7461 +/-1C TDM Extended Temp Range I.C
adt7461 +/-1C TDM Extended Temp Range I.C
+adi,adt7473 +/-1C TDM Extended Temp Range I.C
+adi,adt7475 +/-1C TDM Extended Temp Range I.C
+adi,adt7476 +/-1C TDM Extended Temp Range I.C
+adi,adt7490 +/-1C TDM Extended Temp Range I.C
at,24c08 i2c serial eeprom (24cxx)
+atmel,24c00 i2c serial eeprom (24cxx)
+atmel,24c01 i2c serial eeprom (24cxx)
atmel,24c02 i2c serial eeprom (24cxx)
+atmel,24c04 i2c serial eeprom (24cxx)
+atmel,24c16 i2c serial eeprom (24cxx)
+atmel,24c32 i2c serial eeprom (24cxx)
+atmel,24c64 i2c serial eeprom (24cxx)
+atmel,24c128 i2c serial eeprom (24cxx)
+atmel,24c256 i2c serial eeprom (24cxx)
+atmel,24c512 i2c serial eeprom (24cxx)
+atmel,24c1024 i2c serial eeprom (24cxx)
atmel,at97sc3204t i2c trusted platform module (TPM)
capella,cm32181 CM32181: Ambient Light Sensor
catalyst,24c32 i2c serial eeprom
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
+national,lm63 Temperature sensor with integrated fan control
national,lm75 I2C TEMP SENSOR
national,lm80 Serial Interface ACPI-Compatible Microprocessor System Hardware Monitor
+national,lm85 Temperature sensor with integrated fan control
national,lm92 ±0.33°C Accurate, 12-Bit + Sign Temperature Sensor and Thermal Window Comparator with Two-Wire Interface
nuvoton,npct501 i2c trusted platform module (TPM)
nxp,pca9556 Octal SMBus and I2C registered interface
--- /dev/null
+Austrian Microsystems AS3935 Franklin lightning sensor device driver
+
+Required properties:
+ - compatible: must be "ams,as3935"
+ - reg: SPI chip select number for the device
+ - spi-cpha: SPI Mode 1. Refer to spi/spi-bus.txt for generic SPI
+ slave node bindings.
+ - 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:
+ - ams,tuning-capacitor-pf: Calibration tuning capacitor stepping
+ value 0 - 120pF. This will require using the calibration data from
+ the manufacturer.
+
+Example:
+
+as3935@0 {
+ compatible = "ams,as3935";
+ reg = <0>;
+ spi-cpha;
+ interrupt-parent = <&gpio1>;
+ interrupts = <16 1>;
+ ams,tuning-capacitor-pf = <80>;
+};
- max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than
the maximum frame size (there's contradiction in ePAPR).
- phy-mode: string, operation mode of the PHY interface; supported values are
- "mii", "gmii", "sgmii", "tbi", "rev-mii", "rmii", "rgmii", "rgmii-id",
+ "mii", "gmii", "sgmii", "qsgmii", "tbi", "rev-mii", "rmii", "rgmii", "rgmii-id",
"rgmii-rxid", "rgmii-txid", "rtbi", "smii", "xgmii"; this is now a de-facto
standard property;
- phy-connection-type: the same as "phy-mode" property but described in ePAPR;
Example:
// pin controller node
pinctrl@35004800 {
- compatible = "brcmbcm11351-pinctrl";
+ compatible = "brcm,bcm11351-pinctrl";
reg = <0x35004800 0x430>;
// pin configuration node
* Energymicro efm32 UART
Required properties:
-- compatible : Should be "efm32,uart"
+- compatible : Should be "energymicro,efm32-uart"
- reg : Address and length of the register set
- interrupts : Should contain uart interrupt
Example:
uart@0x4000c400 {
- compatible = "efm32,uart";
+ compatible = "energymicro,efm32-uart";
reg = <0x4000c400 0x400>;
interrupts = <15>;
efm32,location = <0>;
Optional properties:
- interface_pix_fmt: How this display is connected to the
display interface. Currently supported types: "rgb24", "rgb565", "bgr666"
+ and "lvds666".
- edid: verbatim EDID data block describing attached display.
- ddc: phandle describing the i2c bus handling the display data
channel
altr Altera Corp.
amcc Applied Micro Circuits Corporation (APM, formally AMCC)
amd Advanced Micro Devices (AMD), Inc.
+ams AMS AG
amstaos AMS-Taos Inc.
apm Applied Micro Circuits Corporation (APM)
arm ARM Ltd.
avago Avago Technologies
bosch Bosch Sensortec GmbH
brcm Broadcom Corporation
+buffalo Buffalo, Inc.
calxeda Calxeda
capella Capella Microsystems, Inc
cavium Cavium, Inc.
crystalfontz Crystalfontz America, Inc.
dallas Maxim Integrated Products (formerly Dallas Semiconductor)
davicom DAVICOM Semiconductor, Inc.
-dlink D-Link Systems, Inc.
denx Denx Software Engineering
+digi Digi International Inc.
+dlink D-Link Corporation
dmo Data Modul AG
+ebv EBV Elektronik
edt Emerging Display Technologies
emmicro EM Microelectronic
epfl Ecole Polytechnique Fédérale de Lausanne
epson Seiko Epson Corp.
est ESTeem Wireless Modems
eukrea Eukréa Electromatique
+excito Excito
fsl Freescale Semiconductor
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
hisilicon Hisilicon Limited.
honeywell Honeywell
hp Hewlett Packard
+i2se I2SE GmbH
ibm International Business Machines (IBM)
idt Integrated Device Technologies, Inc.
+iom Iomega Corporation
img Imagination Technologies Ltd.
intel Intel Corporation
intercontrol Inter Control Group
+isee ISEE 2007 S.L.
isl Intersil
karo Ka-Ro electronics GmbH
+keymile Keymile GmbH
lacie LaCie
lantiq Lantiq Semiconductor
lg LG Corporation
microchip Microchip Technology Inc.
mosaixtech Mosaix Technologies, Inc.
moxa Moxa
+mpl MPL AG
+mxicy Macronix International Co., Ltd.
national National Semiconductor
neonode Neonode Inc.
netgear NETGEAR
+newhaven Newhaven Display International
nintendo Nintendo
nokia Nokia
nvidia NVIDIA
panasonic Panasonic Corporation
phytec PHYTEC Messtechnik GmbH
picochip Picochip Ltd
+plathome Plat'Home Co., Ltd.
powervr PowerVR (deprecated, use img)
qca Qualcomm Atheros, Inc.
qcom Qualcomm Technologies, Inc
qnap QNAP Systems, Inc.
+raidsonic RaidSonic Technology GmbH
ralink Mediatek/Ralink Technology Corp.
ramtron Ramtron International
realtek Realtek Semiconductor Corp.
samsung Samsung Semiconductor
sbs Smart Battery System
schindler Schindler
+seagate Seagate Technology PLC
sil Silicon Image
silabs Silicon Laboratories
simtek
tlm Trusted Logic Mobility
toshiba Toshiba Corporation
toumaz Toumaz
+usi Universal Scientifc Industrial Co., Ltd.
v3 V3 Semiconductor
via VIA Technologies, Inc.
voipac Voipac Technologies s.r.o.
wm Wondermedia Technologies, Inc.
xes Extreme Engineering Solutions (X-ES)
xlnx Xilinx
+zyxel ZyXEL Communications Corp.
MEM
devm_kzalloc()
devm_kfree()
+ devm_kmemdup()
IIO
devm_iio_device_alloc()
もし、3.x.y カーネルが存在しない場合には、番号が一番大きい 3.x が
最新の安定版カーネルです。
-3.x.y は "stable" チーム <stable@kernel.org> でメンテされており、必
+3.x.y は "stable" チーム <stable@vger.kernel.org> でメンテされており、必
要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ
た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
の場合はこれに対してだいたいの場合、すぐにリリースがされます。
-stable ツリーにパッチを送付する手続き-
- - 上記の規則に従っているかを確認した後に、stable@kernel.org にパッチ
+ - 上記の規則に従っているかを確認した後に、stable@vger.kernel.org にパッチ
を送る。
- 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合
には NAK を受け取る。この反応は開発者たちのスケジュールによって、数
日かかる場合がある。
- もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの
メンテナーによるレビューのために -stable キューに追加される。
- - パッチに stable@kernel.org のアドレスが付加されているときには、それ
+ - パッチに stable@vger.kernel.org のアドレスが付加されているときには、それ
が Linus のツリーに入る時に自動的に stable チームに email される。
- - セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ
+ - セキュリティパッチはこのエイリアス (stable@vger.kernel.org) に送られるべ
きではなく、代わりに security@kernel.org のアドレスに送られる。
レビューサイクル-
dhash_entries= [KNL]
Set number of hash buckets for dentry cache.
- digi= [HW,SERIAL]
- IO parameters + enable/disable command.
-
- digiepca= [HW,SERIAL]
- See drivers/char/README.epca and
- Documentation/serial/digiepca.txt.
-
disable= [IPV6]
See Documentation/networking/ipv6.txt.
rhash_entries= [KNL,NET]
Set number of hash buckets for route cache
- riscom8= [HW,SERIAL]
- Format: <io_board1>[,<io_board2>[,...<io_boardN>]]
-
ro [KNL] Mount root device read-only on boot
root= [KNL] Root filesystem
sonypi.*= [HW] Sony Programmable I/O Control Device driver
See Documentation/laptops/sonypi.txt
- specialix= [HW,SERIAL] Specialix multi-serial port adapter
- See Documentation/serial/specialix.txt.
-
spia_io_base= [HW,MTD]
spia_fio_base=
spia_pedr=
PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h
CMAGIC 0x0111 user include/linux/a.out.h
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel drivers/net/mkiss.h
-RISCOM8_MAGIC 0x0907 riscom_port drivers/char/riscom8.h
-SPECIALIX_MAGIC 0x0907 specialix_port drivers/char/specialix_io8.h
HDLC_MAGIC 0x239e n_hdlc drivers/char/n_hdlc.c
APM_BIOS_MAGIC 0x4101 apm_user arch/x86/kernel/apm_32.c
CYCLADES_MAGIC 0x4359 cyclades_port include/linux/cyclades.h
X25_ASY_MAGIC 0x5303 x25_asy drivers/net/x25_asy.h
SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h
AX25_MAGIC 0x5316 ax_disp drivers/net/mkiss.h
-ESP_MAGIC 0x53ee esp_struct drivers/char/esp.h
TTY_MAGIC 0x5401 tty_struct include/linux/tty.h
MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c
TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h
RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c
USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h
CG_MAGIC 0x00090255 ufs_cylinder_group include/linux/ufs_fs.h
-A2232_MAGIC 0x000a2232 gs_port drivers/char/ser_a2232.h
RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h
LSEMAGIC 0x05091998 lse drivers/fc4/fc.c
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
RIEBL_MAGIC 0x09051990 drivers/net/atarilance.c
-RIO_MAGIC 0x12345678 gs_port drivers/char/rio/rio_linux.c
-SX_MAGIC 0x12345678 gs_port drivers/char/sx.h
NBD_REQUEST_MAGIC 0x12560953 nbd_request include/linux/nbd.h
RED_MAGIC2 0x170fc2a5 (any) mm/slab.c
BAYCOM_MAGIC 0x19730510 baycom_state drivers/net/baycom_epp.c
CTC_ASYNC_MAGIC 0x49344C01 ctc_tty_info drivers/s390/net/ctctty.c
ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s drivers/isdn/i4l/isdn_net_lib.h
SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg arch/*/amiga/config.c
-STLI_BOARDMAGIC 0x4bc6c825 stlibrd include/linux/istallion.h
CS_STATE_MAGIC 0x4c4f4749 cs_state sound/oss/cs46xx.c
SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.c
SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c
GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h
RED_MAGIC1 0x5a2cf071 (any) mm/slab.c
-STL_PORTMAGIC 0x5a7182c9 stlport include/linux/stallion.h
EEPROM_MAGIC_VALUE 0x5ab478d2 lanai_dev drivers/atm/lanai.c
HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state include/linux/hdlcdrv.h
-EPCA_MAGIC 0x5c6df104 channel include/linux/epca.h
PCXX_MAGIC 0x5c6df104 channel drivers/char/pcxx.h
KV_MAGIC 0x5f4b565f kernel_vars_s arch/mips/include/asm/sn/klkernvars.h
I810_STATE_MAGIC 0x63657373 i810_state sound/oss/i810_audio.c
LO_MAGIC 0x68797548 nbd_device include/linux/nbd.h
OPROFILE_MAGIC 0x6f70726f super_block drivers/oprofile/oprofilefs.h
M3_STATE_MAGIC 0x734d724d m3_state sound/oss/maestro3.c
-STL_PANELMAGIC 0x7ef621a1 stlpanel include/linux/stallion.h
VMALLOC_MAGIC 0x87654320 snd_alloc_track sound/core/memory.c
KMALLOC_MAGIC 0x87654321 snd_alloc_track sound/core/memory.c
PWC_MAGIC 0x89DC10AB pwc_device drivers/usb/media/pwc.h
NBD_REPLY_MAGIC 0x96744668 nbd_reply include/linux/nbd.h
-STL_BOARDMAGIC 0xa2267f52 stlbrd include/linux/stallion.h
ENI155_MAGIC 0xa54b872d midway_eprom drivers/atm/eni.h
SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h
CODA_MAGIC 0xC0DAC0DA coda_file_info fs/coda/coda_fs_i.h
DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram drivers/scsi/gdth.h
-STLI_PORTMAGIC 0xe671c7a1 stliport include/linux/istallion.h
YAM_MAGIC 0xF10A7654 yam_port drivers/net/hamradio/yam.c
CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry drivers/scsi/arm/queue.c
- this file.
README.cycladesZ
- info on Cyclades-Z firmware loading.
-digiepca.txt
- - info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards.
driver
- intro to the low level serial driver.
moxa-smartio
- file with info on installing/using Moxa multiport serial driver.
n_gsm.txt
- GSM 0710 tty multiplexer howto.
-riscom8.txt
- - notes on using the RISCom/8 multi-port serial driver.
rocket.txt
- info on the Comtrol RocketPort multiport serial driver.
serial-rs485.txt
- info about RS485 structures and support in the kernel.
-specialix.txt
- - info on hardware/driver for specialix IO8+ multiport serial card.
-sx.txt
- - info on the Specialix SX/SI multiport serial driver.
tty.txt
- guide to the locking policies of the tty layer.
+++ /dev/null
-NOTE: This driver is obsolete. Digi provides a 2.6 driver (dgdm) at
-http://www.digi.com for PCI cards. They no longer maintain this driver,
-and have no 2.6 driver for ISA cards.
-
-This driver requires a number of user-space tools. They can be acquired from
-http://www.digi.com, but only works with 2.4 kernels.
-
-
-The Digi Intl. epca driver.
-----------------------------
-The Digi Intl. epca driver for Linux supports the following boards:
-
-Digi PC/Xem, PC/Xr, PC/Xe, PC/Xi, PC/Xeve
-Digi EISA/Xem, PCI/Xem, PCI/Xr
-
-Limitations:
-------------
-Currently the driver only autoprobes for supported PCI boards.
-
-The Linux MAKEDEV command does not support generating the Digiboard
-Devices. Users executing digiConfig to setup EISA and PC series cards
-will have their device nodes automatically constructed (cud?? for ~CLOCAL,
-and ttyD?? for CLOCAL). Users wishing to boot their board from the LILO
-prompt, or those users booting PCI cards may use buildDIGI to construct
-the necessary nodes.
-
-Notes:
-------
-This driver may be configured via LILO. For users who have already configured
-their driver using digiConfig, configuring from LILO will override previous
-settings. Multiple boards may be configured by issuing multiple LILO command
-lines. For examples see the bottom of this document.
-
-Device names start at 0 and continue up. Beware of this as previous Digi
-drivers started device names with 1.
-
-PCI boards are auto-detected and configured by the driver. PCI boards will
-be allocated device numbers (internally) beginning with the lowest PCI slot
-first. In other words a PCI card in slot 3 will always have higher device
-nodes than a PCI card in slot 1.
-
-LILO config examples:
----------------------
-Using LILO's APPEND command, a string of comma separated identifiers or
-integers can be used to configure supported boards. The six values in order
-are:
-
- Enable/Disable this card or Override,
- Type of card: PC/Xe (AccelePort) (0), PC/Xeve (1), PC/Xem or PC/Xr (2),
- EISA/Xem (3), PC/64Xe (4), PC/Xi (5),
- Enable/Disable alternate pin arrangement,
- Number of ports on this card,
- I/O Port where card is configured (in HEX if using string identifiers),
- Base of memory window (in HEX if using string identifiers),
-
-NOTE : PCI boards are auto-detected and configured. Do not attempt to
-configure PCI boards with the LILO append command. If you wish to override
-previous configuration data (As set by digiConfig), but you do not wish to
-configure any specific card (Example if there are PCI cards in the system)
-the following override command will accomplish this:
--> append="digi=2"
-
-Samples:
- append="digiepca=E,PC/Xe,D,16,200,D0000"
- or
- append="digi=1,0,0,16,512,851968"
-
-Supporting Tools:
------------------
-Supporting tools include digiDload, digiConfig, buildPCI, and ditty. See
-drivers/char/README.epca for more details. Note,
-this driver REQUIRES that digiDload be executed prior to it being used.
-Failure to do this will result in an ENODEV error.
-
-Documentation:
---------------
-Complete documentation for this product may be found in the tool package.
-
-Sources of information and support:
------------------------------------
-Digi Intl. support site for this product:
-
--> http://www.digi.com
-
-Acknowledgments:
-----------------
-Much of this work (And even text) was derived from a similar document
-supporting the original public domain DigiBoard driver Copyright (C)
-1994,1995 Troy De Jongh. Many thanks to Christoph Lameter
-(christoph@lameter.com) and Mike McLagan (mike.mclagan@linux.org) who authored
-and contributed to the original document.
-
-Changelog:
-----------
-10-29-04: Update status of driver, remove dead links in document
- James Nelson <james4765@gmail.com>
-
-2000 (?) Original Document
+++ /dev/null
-* NOTE - this is an unmaintained driver. The original author cannot be located.
-
-SDL Communications is now SBS Technologies, and does not have any
-information on these ancient ISA cards on their website.
-
-James Nelson <james4765@gmail.com> - 12-12-2004
-
- This is the README for RISCom/8 multi-port serial driver
- (C) 1994-1996 D.Gorodchanin
- See file LICENSE for terms and conditions.
-
-NOTE: English is not my native language.
- I'm sorry for any mistakes in this text.
-
-Misc. notes for RISCom/8 serial driver, in no particular order :)
-
-1) This driver can support up to 4 boards at time.
- Use string "riscom8=0xXXX,0xXXX,0xXXX,0xXXX" at LILO prompt, for
- setting I/O base addresses for boards. If you compile driver
- as module use modprobe options "iobase=0xXXX iobase1=0xXXX iobase2=..."
-
-2) The driver partially supports famous 'setserial' program, you can use almost
- any of its options, excluding port & irq settings.
-
-3) There are some misc. defines at the beginning of riscom8.c, please read the
- comments and try to change some of them in case of problems.
-
-4) I consider the current state of the driver as BETA.
-
-5) SDL Communications WWW page is http://www.sdlcomm.com.
-
-6) You can use the MAKEDEV program to create RISCom/8 /dev/ttyL* entries.
-
-7) Minor numbers for first board are 0-7, for second 8-15, etc.
-
-22 Apr 1996.
+++ /dev/null
-
- specialix.txt -- specialix IO8+ multiport serial driver readme.
-
-
-
- Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl)
-
- Specialix pays for the development and support of this driver.
- Please DO contact io8-linux@specialix.co.uk if you require
- support.
-
- This driver was developed in the BitWizard linux device
- driver service. If you require a linux device driver for your
- product, please contact devices@BitWizard.nl for a quote.
-
- This code is firmly based on the riscom/8 serial driver,
- written by Dmitry Gorodchanin. The specialix IO8+ card
- programming information was obtained from the CL-CD1865 Data
- Book, and Specialix document number 6200059: IO8+ Hardware
- Functional Specification, augmented by document number 6200088:
- Merak Hardware Functional Specification. (IO8+/PCI is also
- called Merak)
-
-
- 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.
-
- 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.
-
-
-Intro
-=====
-
-
-This file contains some random information, that I like to have online
-instead of in a manual that can get lost. Ever misplace your Linux
-kernel sources? And the manual of one of the boards in your computer?
-
-
-Addresses and interrupts
-========================
-
-Address dip switch settings:
-The dip switch sets bits 2-9 of the IO address.
-
- 9 8 7 6 5 4 3 2
- +-----------------+
- 0 | X X X X X X X |
- | | = IoBase = 0x100
- 1 | X |
- +-----------------+ ------ RS232 connectors ---->
-
- | | |
- edge connector
- | | |
- V V V
-
-Base address 0x100 caused a conflict in one of my computers once. I
-haven't the foggiest why. My Specialix card is now at 0x180. My
-other computer runs just fine with the Specialix card at 0x100....
-The card occupies 4 addresses, but actually only two are really used.
-
-The PCI version doesn't have any dip switches. The BIOS assigns
-an IO address.
-
-The driver now still autoprobes at 0x100, 0x180, 0x250 and 0x260. If
-that causes trouble for you, please report that. I'll remove
-autoprobing then.
-
-The driver will tell the card what IRQ to use, so you don't have to
-change any jumpers to change the IRQ. Just use a command line
-argument (irq=xx) to the insmod program to set the interrupt.
-
-The BIOS assigns the IRQ on the PCI version. You have no say in what
-IRQ to use in that case.
-
-If your specialix cards are not at the default locations, you can use
-the kernel command line argument "specialix=io0,irq0,io1,irq1...".
-Here "io0" is the io address for the first card, and "irq0" is the
-irq line that the first card should use. And so on.
-
-Examples.
-
-You use the driver as a module and have three cards at 0x100, 0x250
-and 0x180. And some way or another you want them detected in that
-order. Moreover irq 12 is taken (e.g. by your PS/2 mouse).
-
- insmod specialix.o iobase=0x100,0x250,0x180 irq=9,11,15
-
-The same three cards, but now in the kernel would require you to
-add
-
- specialix=0x100,9,0x250,11,0x180,15
-
-to the command line. This would become
-
- append="specialix=0x100,9,0x250,11,0x180,15"
-
-in your /etc/lilo.conf file if you use lilo.
-
-The Specialix driver is slightly odd: It allows you to have the second
-or third card detected without having a first card. This has
-advantages and disadvantages. A slot that isn't filled by an ISA card,
-might be filled if a PCI card is detected. Thus if you have an ISA
-card at 0x250 and a PCI card, you would get:
-
-sx0: specialix IO8+ Board at 0x100 not found.
-sx1: specialix IO8+ Board at 0x180 not found.
-sx2: specialix IO8+ board detected at 0x250, IRQ 12, CD1865 Rev. B.
-sx3: specialix IO8+ Board at 0x260 not found.
-sx0: specialix IO8+ board detected at 0xd800, IRQ 9, CD1865 Rev. B.
-
-This would happen if you don't give any probe hints to the driver.
-If you would specify:
-
- specialix=0x250,11
-
-you'd get the following messages:
-
-sx0: specialix IO8+ board detected at 0x250, IRQ 11, CD1865 Rev. B.
-sx1: specialix IO8+ board detected at 0xd800, IRQ 9, CD1865 Rev. B.
-
-ISA probing is aborted after the IO address you gave is exhausted, and
-the PCI card is now detected as the second card. The ISA card is now
-also forced to IRQ11....
-
-
-Baud rates
-==========
-
-The rev 1.2 and below boards use a CL-CD1864. These chips can only
-do 64kbit. The rev 1.3 and newer boards use a CL-CD1865. These chips
-are officially capable of 115k2.
-
-The Specialix card uses a 25MHz crystal (in times two mode, which in
-fact is a divided by two mode). This is not enough to reach the rated
-115k2 on all ports at the same time. With this clock rate you can only
-do 37% of this rate. This means that at 115k2 on all ports you are
-going to lose characters (The chip cannot handle that many incoming
-bits at this clock rate.) (Yes, you read that correctly: there is a
-limit to the number of -=bits=- per second that the chip can handle.)
-
-If you near the "limit" you will first start to see a graceful
-degradation in that the chip cannot keep the transmitter busy at all
-times. However with a central clock this slow, you can also get it to
-miss incoming characters. The driver will print a warning message when
-you are outside the official specs. The messages usually show up in
-the file /var/log/messages .
-
-The specialix card cannot reliably do 115k2. If you use it, you have
-to do "extensive testing" (*) to verify if it actually works.
-
-When "mgetty" communicates with my modem at 115k2 it reports:
-got: +++[0d]ATQ0V1H0[0d][0d][8a]O[cb][0d][8a]
- ^^^^ ^^^^ ^^^^
-
-The three characters that have the "^^^" under them have suffered a
-bit error in the highest bit. In conclusion: I've tested it, and found
-that it simply DOESN'T work for me. I also suspect that this is also
-caused by the baud rate being just a little bit out of tune.
-
-I upgraded the crystal to 66Mhz on one of my Specialix cards. Works
-great! Contact me for details. (Voids warranty, requires a steady hand
-and more such restrictions....)
-
-
-(*) Cirrus logic CD1864 databook, page 40.
-
-
-Cables for the Specialix IO8+
-=============================
-
-The pinout of the connectors on the IO8+ is:
-
- pin short direction long name
- name
- Pin 1 DCD input Data Carrier Detect
- Pin 2 RXD input Receive
- Pin 3 DTR/RTS output Data Terminal Ready/Ready To Send
- Pin 4 GND - Ground
- Pin 5 TXD output Transmit
- Pin 6 CTS input Clear To Send
-
-
- -- 6 5 4 3 2 1 --
- | |
- | |
- | |
- | |
- +----- -----+
- |__________|
- clip
-
- Front view of an RJ12 connector. Cable moves "into" the paper.
- (the plug is ready to plug into your mouth this way...)
-
-
- NULL cable. I don't know who is going to use these except for
- testing purposes, but I tested the cards with this cable. (It
- took quite a while to figure out, so I'm not going to delete
- it. So there! :-)
-
-
- This end goes This end needs
- straight into the some twists in
- RJ12 plug. the wiring.
- IO8+ RJ12 IO8+ RJ12
- 1 DCD white -
- - - 1 DCD
- 2 RXD black 5 TXD
- 3 DTR/RTS red 6 CTS
- 4 GND green 4 GND
- 5 TXD yellow 2 RXD
- 6 CTS blue 3 DTR/RTS
-
-
- Same NULL cable, but now sorted on the second column.
-
- 1 DCD white -
- - - 1 DCD
- 5 TXD yellow 2 RXD
- 6 CTS blue 3 DTR/RTS
- 4 GND green 4 GND
- 2 RXD black 5 TXD
- 3 DTR/RTS red 6 CTS
-
-
-
- This is a modem cable usable for hardware handshaking:
- RJ12 DB25 DB9
- 1 DCD white 8 DCD 1 DCD
- 2 RXD black 3 RXD 2 RXD
- 3 DTR/RTS red 4 RTS 7 RTS
- 4 GND green 7 GND 5 GND
- 5 TXD yellow 2 TXD 3 TXD
- 6 CTS blue 5 CTS 8 CTS
- +---- 6 DSR 6 DSR
- +---- 20 DTR 4 DTR
-
- This is a modem cable usable for software handshaking:
- It allows you to reset the modem using the DTR ioctls.
- I (REW) have never tested this, "but xxxxxxxxxxxxx
- says that it works." If you test this, please
- tell me and I'll fill in your name on the xxx's.
-
- RJ12 DB25 DB9
- 1 DCD white 8 DCD 1 DCD
- 2 RXD black 3 RXD 2 RXD
- 3 DTR/RTS red 20 DTR 4 DTR
- 4 GND green 7 GND 5 GND
- 5 TXD yellow 2 TXD 3 TXD
- 6 CTS blue 5 CTS 8 CTS
- +---- 6 DSR 6 DSR
- +---- 4 RTS 7 RTS
-
- I bought a 6 wire flat cable. It was colored as indicated.
- Check that yours is the same before you trust me on this.
-
-
-Hardware handshaking issues.
-============================
-
-The driver can be told to operate in two different ways. The default
-behaviour is specialix.sx_rtscts = 0 where the pin behaves as DTR when
-hardware handshaking is off. It behaves as the RTS hardware
-handshaking signal when hardware handshaking is selected.
-
-When you use this, you have to use the appropriate cable. The
-cable will either be compatible with hardware handshaking or with
-software handshaking. So switching on the fly is not really an
-option.
-
-I actually prefer to use the "specialix.sx_rtscts=1" option.
-This makes the DTR/RTS pin always an RTS pin, and ioctls to
-change DTR are always ignored. I have a cable that is configured
-for this.
-
-
-Ports and devices
-=================
-
-Port 0 is the one furthest from the card-edge connector.
-
-Devices:
-
-You should make the devices as follows:
-
-bash
-cd /dev
-for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \
- 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
-do
- echo -n "$i "
- mknod /dev/ttyW$i c 75 $i
- mknod /dev/cuw$i c 76 $i
-done
-echo ""
-
-If your system doesn't come with these devices preinstalled, bug your
-linux-vendor about this. They have had ample time to get this
-implemented by now.
-
-You cannot have more than 4 boards in one computer. The card only
-supports 4 different interrupts. If you really want this, contact me
-about this and I'll give you a few tips (requires soldering iron)....
-
-If you have enough PCI slots, you can probably use more than 4 PCI
-versions of the card though....
-
-The PCI version of the card cannot adhere to the mechanical part of
-the PCI spec because the 8 serial connectors are simply too large. If
-it doesn't fit in your computer, bring back the card.
-
-
-------------------------------------------------------------------------
-
-
- Fixed bugs and restrictions:
- - During initialization, interrupts are blindly turned on.
- Having a shadow variable would cause an extra memory
- access on every IO instruction.
- - The interrupt (on the card) should be disabled when we
- don't allocate the Linux end of the interrupt. This allows
- a different driver/card to use it while all ports are not in
- use..... (a la standard serial port)
- == An extra _off variant of the sx_in and sx_out macros are
- now available. They don't set the interrupt enable bit.
- These are used during initialization. Normal operation uses
- the old variant which enables the interrupt line.
- - RTS/DTR issue needs to be implemented according to
- specialix' spec.
- I kind of like the "determinism" of the current
- implementation. Compile time flag?
- == Ok. Compile time flag! Default is how Specialix likes it.
- == Now a config time flag! Gets saved in your config file. Neat!
- - Can you set the IO address from the lilo command line?
- If you need this, bug me about it, I'll make it.
- == Hah! No bugging needed. Fixed! :-)
- - Cirrus logic hasn't gotten back to me yet why the CD1865 can
- and the CD1864 can't do 115k2. I suspect that this is
- because the CD1864 is not rated for 33MHz operation.
- Therefore the CD1864 versions of the card can't do 115k2 on
- all ports just like the CD1865 versions. The driver does
- not block 115k2 on CD1864 cards.
- == I called the Cirrus Logic representative here in Holland.
- The CD1864 databook is identical to the CD1865 databook,
- except for an extra warning at the end. Similar Bit errors
- have been observed in testing at 115k2 on both an 1865 and
- a 1864 chip. I see no reason why I would prohibit 115k2 on
- 1864 chips and not do it on 1865 chips. Actually there is
- reason to prohibit it on BOTH chips. I print a warning.
- If you use 115k2, you're on your own.
- - A spiky CD may send spurious HUPs. Also in CLOCAL???
- -- A fix for this turned out to be counter productive.
- Different fix? Current behaviour is acceptable?
- -- Maybe the current implementation is correct. If anybody
- gets bitten by this, please report, and it will get fixed.
-
- -- Testing revealed that when in CLOCAL, the problem doesn't
- occur. As warned for in the CD1865 manual, the chip may
- send modem intr's on a spike. We could filter those out,
- but that would be a cludge anyway (You'd still risk getting
- a spurious HUP when two spikes occur.).....
-
-
-
- Bugs & restrictions:
- - This is a difficult card to autoprobe.
- You have to WRITE to the address register to even
- read-probe a CD186x register. Disable autodetection?
- -- Specialix: any suggestions?
-
-
+++ /dev/null
-
- sx.txt -- specialix SX/SI multiport serial driver readme.
-
-
-
- Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl)
-
- Specialix pays for the development and support of this driver.
- Please DO contact support@specialix.co.uk if you require
- support.
-
- This driver was developed in the BitWizard linux device
- driver service. If you require a linux device driver for your
- product, please contact devices@BitWizard.nl for a quote.
-
- (History)
- There used to be an SI driver by Simon Allan. This is a complete
- rewrite from scratch. Just a few lines-of-code have been snatched.
-
- (Sources)
- Specialix document number 6210028: SX Host Card and Download Code
- Software Functional Specification.
-
- (Copying)
- 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.
-
- 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.
-
- (Addendum)
- I'd appreciate it that if you have fixes, that you send them
- to me first.
-
-
-Introduction
-============
-
-This file contains some random information, that I like to have online
-instead of in a manual that can get lost. Ever misplace your Linux
-kernel sources? And the manual of one of the boards in your computer?
-
-
-Theory of operation
-===================
-
-An important thing to know is that the driver itself doesn't have the
-firmware for the card. This means that you need the separate package
-"sx_firmware". For now you can get the source at
-
- ftp://ftp.bitwizard.nl/specialix/sx_firmware_<version>.tgz
-
-The firmware load needs a "misc" device, so you'll need to enable the
-"Support for user misc device modules" in your kernel configuration.
-The misc device needs to be called "/dev/specialix_sxctl". It needs
-misc major 10, and minor number 167 (assigned by HPA). The section
-on creating device files below also creates this device.
-
-After loading the sx.o module into your kernel, the driver will report
-the number of cards detected, but because it doesn't have any
-firmware, it will not be able to determine the number of ports. Only
-when you then run "sx_firmware" will the firmware be downloaded and
-the rest of the driver initialized. At that time the sx_firmware
-program will report the number of ports installed.
-
-In contrast with many other multi port serial cards, some of the data
-structures are only allocated when the card knows the number of ports
-that are connected. This means we won't waste memory for 120 port
-descriptor structures when you only have 8 ports. If you experience
-problems due to this, please report them: I haven't seen any.
-
-
-Interrupts
-==========
-
-A multi port serial card, would generate a horrendous amount of
-interrupts if it would interrupt the CPU for every received
-character. Even more than 10 years ago, the trick not to use
-interrupts but to poll the serial cards was invented.
-
-The SX card allow us to do this two ways. First the card limits its
-own interrupt rate to a rate that won't overwhelm the CPU. Secondly,
-we could forget about the cards interrupt completely and use the
-internal timer for this purpose.
-
-Polling the card can take up to a few percent of your CPU. Using the
-interrupts would be better if you have most of the ports idle. Using
-timer-based polling is better if your card almost always has work to
-do. You save the separate interrupt in that case.
-
-In any case, it doesn't really matter all that much.
-
-The most common problem with interrupts is that for ISA cards in a PCI
-system the BIOS has to be told to configure that interrupt as "legacy
-ISA". Otherwise the card can pull on the interrupt line all it wants
-but the CPU won't see this.
-
-If you can't get the interrupt to work, remember that polling mode is
-more efficient (provided you actually use the card intensively).
-
-
-Allowed Configurations
-======================
-
-Some configurations are disallowed. Even though at a glance they might
-seem to work, they are known to lockup the bus between the host card
-and the device concentrators. You should respect the drivers decision
-not to support certain configurations. It's there for a reason.
-
-Warning: Seriously technical stuff ahead. Executive summary: Don't use
-SX cards except configured at a 64k boundary. Skip the next paragraph.
-
-The SX cards can theoretically be placed at a 32k boundary. So for
-instance you can put an SX card at 0xc8000-0xd7fff. This is not a
-"recommended configuration". ISA cards have to tell the bus controller
-how they like their timing. Due to timing issues they have to do this
-based on which 64k window the address falls into. This means that the
-32k window below and above the SX card have to use exactly the same
-timing as the SX card. That reportedly works for other SX cards. But
-you're still left with two useless 32k windows that should not be used
-by anybody else.
-
-
-Configuring the driver
-======================
-
-PCI cards are always detected. The driver auto-probes for ISA cards at
-some sensible addresses. Please report if the auto-probe causes trouble
-in your system, or when a card isn't detected.
-
-I'm afraid I haven't implemented "kernel command line parameters" yet.
-This means that if the default doesn't work for you, you shouldn't use
-the compiled-into-the-kernel version of the driver. Use a module
-instead. If you convince me that you need this, I'll make it for
-you. Deal?
-
-I'm afraid that the module parameters are a bit clumsy. If you have a
-better idea, please tell me.
-
-You can specify several parameters:
-
- sx_poll: number of jiffies between timer-based polls.
-
- Set this to "0" to disable timer based polls.
- Initialization of cards without a working interrupt
- will fail.
-
- Set this to "1" if you want a polling driver.
- (on Intel: 100 polls per second). If you don't use
- fast baud rates, you might consider a value like "5".
- (If you don't know how to do the math, use 1).
-
- sx_slowpoll: Number of jiffies between timer-based polls.
- Set this to "100" to poll once a second.
- This should get the card out of a stall if the driver
- ever misses an interrupt. I've never seen this happen,
- and if it does, that's a bug. Tell me.
-
- sx_maxints: Number of interrupts to request from the card.
- The card normally limits interrupts to about 100 per
- second to offload the host CPU. You can increase this
- number to reduce latency on the card a little.
- Note that if you give a very high number you can overload
- your CPU as well as the CPU on the host card. This setting
- is inaccurate and not recommended for SI cards (But it
- works).
-
- sx_irqmask: The mask of allowable IRQs to use. I suggest you set
- this to 0 (disable IRQs all together) and use polling if
- the assignment of IRQs becomes problematic. This is defined
- as the sum of (1 << irq) 's that you want to allow. So
- sx_irqmask of 8 (1 << 3) specifies that only irq 3 may
- be used by the SX driver. If you want to specify to the
- driver: "Either irq 11 or 12 is ok for you to use", then
- specify (1 << 11) | (1 << 12) = 0x1800 .
-
- sx_debug: You can enable different sorts of debug traces with this.
- At "-1" all debugging traces are active. You'll get several
- times more debugging output than you'll get characters
- transmitted.
-
-
-Baud rates
-==========
-
-Theoretically new SXDCs should be capable of more than 460k
-baud. However the line drivers usually give up before that. Also the
-CPU on the card may not be able to handle 8 channels going at full
-blast at that speed. Moreover, the buffers are not large enough to
-allow operation with 100 interrupts per second. You'll have to realize
-that the card has a 256 byte buffer, so you'll have to increase the
-number of interrupts per second if you have more than 256*100 bytes
-per second to transmit. If you do any performance testing in this
-area, I'd be glad to hear from you...
-
-(Psst Linux users..... I think the Linux driver is more efficient than
-the driver for other OSes. If you can and want to benchmark them
-against each other, be my guest, and report your findings...... :-)
-
-
-Ports and devices
-=================
-
-Port 0 is the top connector on the module closest to the host
-card. Oh, the ports on the SXDCs and TAs are labelled from 1 to 8
-instead of from 0 to 7, as they are numbered by linux. I'm stubborn in
-this: I know for sure that I wouldn't be able to calculate which port
-is which anymore if I would change that....
-
-
-Devices:
-
-You should make the device files as follows:
-
-#!/bin/sh
-# (I recommend that you cut-and-paste this into a file and run that)
-cd /dev
-t=0
-mknod specialix_sxctl c 10 167
-while [ $t -lt 64 ]
- do
- echo -n "$t "
- mknod ttyX$t c 32 $t
- mknod cux$t c 33 $t
- t=`expr $t + 1`
-done
-echo ""
-rm /etc/psdevtab
-ps > /dev/null
-
-
-This creates 64 devices. If you have more, increase the constant on
-the line with "while". The devices start at 0, as is customary on
-Linux. Specialix seems to like starting the numbering at 1.
-
-If your system doesn't come with these devices pre-installed, bug your
-linux-vendor about this. They should have these devices
-"pre-installed" before the new millennium. The "ps" stuff at the end
-is to "tell" ps that the new devices exist.
-
-Officially the maximum number of cards per computer is 4. This driver
-however supports as many cards in one machine as you want. You'll run
-out of interrupts after a few, but you can switch to polled operation
-then. At about 256 ports (More than 8 cards), we run out of minor
-device numbers. Sorry. I suggest you buy a second computer.... (Or
-switch to RIO).
-
-------------------------------------------------------------------------
-
-
- Fixed bugs and restrictions:
- - Hangup processing.
- -- Done.
-
- - the write path in generic_serial (lockup / oops).
- -- Done (Ugly: not the way I want it. Copied from serial.c).
-
- - write buffer isn't flushed at close.
- -- Done. I still seem to lose a few chars at close.
- Sorry. I think that this is a firmware issue. (-> Specialix)
-
- - drain hardware before changing termios
- - Change debug on the fly.
- - ISA free irq -1. (no firmware loaded).
- - adding c8000 as a probe address. Added warning.
- - Add a RAMtest for the RAM on the card.c
- - Crash when opening a port "way" of the number of allowed ports.
- (for example opening port 60 when there are only 24 ports attached)
- - Sometimes the use-count strays a bit. After a few hours of
- testing the use count is sometimes "3". If you are not like
- me and can remember what you did to get it that way, I'd
- appreciate an Email. Possibly fixed. Tell me if anyone still
- sees this.
- - TAs don't work right if you don't connect all the modem control
- signals. SXDCs do. T225 firmware problem -> Specialix.
- (Mostly fixed now, I think. Tell me if you encounter this!)
-
- Bugs & restrictions:
-
- - Arbitrary baud rates. Requires firmware update. (-> Specialix)
-
- - Low latency (mostly firmware, -> Specialix)
-
-
-
the stable tree without anything else needing to be done by the author
or subsystem maintainer.
- If the patch requires other patches as prerequisites which can be
- cherry-picked than this can be specified in the following format in
+ cherry-picked, then this can be specified in the following format in
the sign-off area:
Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle
allocation fails, the kernel will search other nodes, in order of
increasing distance from the preferred node based on information
provided by the platform firmware.
- containing the cpu where the allocation takes place.
Internally, the Preferred policy uses a single node--the
preferred_node member of struct mempolicy. When the internal
For example, consider a task that is attached to a cpuset with
mems 2-5 that sets an Interleave policy over the same set with
MPOL_F_RELATIVE_NODES. If the cpuset's mems change to 3-7, the
- interleave now occurs over nodes 3,5-6. If the cpuset's mems
+ interleave now occurs over nodes 3,5-7. If the cpuset's mems
then change to 0,2-3,5, then the interleave occurs over nodes
- 0,3,5.
+ 0,2-3,5.
Thanks to the consistent remapping, applications preparing
nodemasks to specify memory policies using this flag should
如果没有2.6.x.y版本内核存在,那么最新的2.6.x版本内核就相当于是当前的稳定
版内核。
-2.6.x.y版本由“稳定版”小组(邮件地址<stable@kernel.org>)维护,一般隔周发
+2.6.x.y版本由“稳定版”小组(邮件地址<stable@vger.kernel.org>)维护,一般隔周发
布新版本。
内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定
--- /dev/null
+Chinese translated version of Documentation/io_orderings.txt
+
+If you have any comment or update to the content, please contact the
+original document maintainer directly. However, if you have a problem
+communicating in English you can also ask the Chinese maintainer for
+help. Contact the Chinese maintainer if this translation is outdated
+or if there is a problem with the translation.
+
+Chinese maintainer: Lin Yongting <linyongting@gmail.com>
+---------------------------------------------------------------------
+Documentation/io_ordering.txt 的中文翻译
+
+如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
+交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
+译存在问题,请联系中文版维护者。
+
+中文版维护者: 林永听 Lin Yongting <linyongting@gmail.com>
+中文版翻译者: 林永听 Lin Yongting <linyongting@gmail.com>
+中文版校译者: 林永听 Lin Yongting <linyongting@gmail.com>
+
+
+以下为正文
+---------------------------------------------------------------------
+
+在某些平台上,所谓的内存映射I/O是弱顺序。在这些平台上,驱动开发者有责任
+保证I/O内存映射地址的写操作按程序图意的顺序达到设备。通常读取一个“安全”
+设备寄存器或桥寄存器,触发IO芯片清刷未处理的写操作到达设备后才处理读操作,
+而达到保证目的。驱动程序通常在spinlock保护的临界区退出之前使用这种技术。
+这也可以保证后面的写操作只在前面的写操作之后到达设备(这非常类似于内存
+屏障操作,mb(),不过仅适用于I/O)。
+
+假设一个设备驱动程的具体例子:
+
+ ...
+CPU A: spin_lock_irqsave(&dev_lock, flags)
+CPU A: val = readl(my_status);
+CPU A: ...
+CPU A: writel(newval, ring_ptr);
+CPU A: spin_unlock_irqrestore(&dev_lock, flags)
+ ...
+CPU B: spin_lock_irqsave(&dev_lock, flags)
+CPU B: val = readl(my_status);
+CPU B: ...
+CPU B: writel(newval2, ring_ptr);
+CPU B: spin_unlock_irqrestore(&dev_lock, flags)
+ ...
+
+上述例子中,设备可能会先接收到newval2的值,然后接收到newval的值,问题就
+发生了。不过很容易通过下面方法来修复:
+
+ ...
+CPU A: spin_lock_irqsave(&dev_lock, flags)
+CPU A: val = readl(my_status);
+CPU A: ...
+CPU A: writel(newval, ring_ptr);
+CPU A: (void)readl(safe_register); /* 配置寄存器?*/
+CPU A: spin_unlock_irqrestore(&dev_lock, flags)
+ ...
+CPU B: spin_lock_irqsave(&dev_lock, flags)
+CPU B: val = readl(my_status);
+CPU B: ...
+CPU B: writel(newval2, ring_ptr);
+CPU B: (void)readl(safe_register); /* 配置寄存器?*/
+CPU B: spin_unlock_irqrestore(&dev_lock, flags)
+
+在解决方案中,读取safe_register寄存器,触发IO芯片清刷未处理的写操作,
+再处理后面的读操作,防止引发数据不一致问题。
PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h
CMAGIC 0x0111 user include/linux/a.out.h
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel drivers/net/mkiss.h
-RISCOM8_MAGIC 0x0907 riscom_port drivers/char/riscom8.h
-SPECIALIX_MAGIC 0x0907 specialix_port drivers/char/specialix_io8.h
HDLC_MAGIC 0x239e n_hdlc drivers/char/n_hdlc.c
APM_BIOS_MAGIC 0x4101 apm_user arch/x86/kernel/apm_32.c
CYCLADES_MAGIC 0x4359 cyclades_port include/linux/cyclades.h
X25_ASY_MAGIC 0x5303 x25_asy drivers/net/x25_asy.h
SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h
AX25_MAGIC 0x5316 ax_disp drivers/net/mkiss.h
-ESP_MAGIC 0x53ee esp_struct drivers/char/esp.h
TTY_MAGIC 0x5401 tty_struct include/linux/tty.h
MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c
TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h
RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c
USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h
CG_MAGIC 0x00090255 ufs_cylinder_group include/linux/ufs_fs.h
-A2232_MAGIC 0x000a2232 gs_port drivers/char/ser_a2232.h
RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h
LSEMAGIC 0x05091998 lse drivers/fc4/fc.c
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
RIEBL_MAGIC 0x09051990 drivers/net/atarilance.c
-RIO_MAGIC 0x12345678 gs_port drivers/char/rio/rio_linux.c
-SX_MAGIC 0x12345678 gs_port drivers/char/sx.h
NBD_REQUEST_MAGIC 0x12560953 nbd_request include/linux/nbd.h
RED_MAGIC2 0x170fc2a5 (any) mm/slab.c
BAYCOM_MAGIC 0x19730510 baycom_state drivers/net/baycom_epp.c
CTC_ASYNC_MAGIC 0x49344C01 ctc_tty_info drivers/s390/net/ctctty.c
ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s drivers/isdn/i4l/isdn_net_lib.h
SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg arch/*/amiga/config.c
-STLI_BOARDMAGIC 0x4bc6c825 stlibrd include/linux/istallion.h
CS_STATE_MAGIC 0x4c4f4749 cs_state sound/oss/cs46xx.c
SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.c
SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c
GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h
RED_MAGIC1 0x5a2cf071 (any) mm/slab.c
-STL_PORTMAGIC 0x5a7182c9 stlport include/linux/stallion.h
EEPROM_MAGIC_VALUE 0x5ab478d2 lanai_dev drivers/atm/lanai.c
HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state include/linux/hdlcdrv.h
-EPCA_MAGIC 0x5c6df104 channel include/linux/epca.h
PCXX_MAGIC 0x5c6df104 channel drivers/char/pcxx.h
KV_MAGIC 0x5f4b565f kernel_vars_s arch/mips/include/asm/sn/klkernvars.h
I810_STATE_MAGIC 0x63657373 i810_state sound/oss/i810_audio.c
LO_MAGIC 0x68797548 nbd_device include/linux/nbd.h
OPROFILE_MAGIC 0x6f70726f super_block drivers/oprofile/oprofilefs.h
M3_STATE_MAGIC 0x734d724d m3_state sound/oss/maestro3.c
-STL_PANELMAGIC 0x7ef621a1 stlpanel include/linux/stallion.h
VMALLOC_MAGIC 0x87654320 snd_alloc_track sound/core/memory.c
KMALLOC_MAGIC 0x87654321 snd_alloc_track sound/core/memory.c
PWC_MAGIC 0x89DC10AB pwc_device drivers/usb/media/pwc.h
NBD_REPLY_MAGIC 0x96744668 nbd_reply include/linux/nbd.h
-STL_BOARDMAGIC 0xa2267f52 stlbrd include/linux/stallion.h
ENI155_MAGIC 0xa54b872d midway_eprom drivers/atm/eni.h
SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h
CODA_MAGIC 0xC0DAC0DA coda_file_info include/linux/coda_fs_i.h
DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram drivers/scsi/gdth.h
-STLI_PORTMAGIC 0xe671c7a1 stliport include/linux/istallion.h
YAM_MAGIC 0xF10A7654 yam_port drivers/net/hamradio/yam.c
CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry drivers/scsi/arm/queue.c
向稳定版代码树提交补丁的过程:
- - 在确认了补丁符合以上的规则后,将补丁发送到stable@kernel.org。
+ - 在确认了补丁符合以上的规则后,将补丁发送到stable@vger.kernel.org。
- 如果补丁被接受到队列里,发送者会收到一个ACK回复,如果没有被接受,收
到的是NAK回复。回复需要几天的时间,这取决于开发者的时间安排。
- 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。
M: Peter Zijlstra <a.p.zijlstra@chello.nl>
M: Paul Mackerras <paulus@samba.org>
M: Ingo Molnar <mingo@redhat.com>
-M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
+M: Arnaldo Carvalho de Melo <acme@kernel.org>
L: linux-kernel@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
S: Supported
SPEAR PLATFORM SUPPORT
M: Viresh Kumar <viresh.linux@gmail.com>
-M: Shiraz Hashim <shiraz.hashim@st.com>
+M: Shiraz Hashim <shiraz.linux.kernel@gmail.com>
L: spear-devel@list.st.com
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
W: http://www.st.com/spear
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 SM7XX FRAME BUFFER DRIVER
M: Teddy Wang <teddy.wang@siliconmotion.com.cn>
S: Odd Fixes
VERSION = 3
PATCHLEVEL = 15
SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc3
NAME = Shuffling Zombie Juror
# *DOCUMENTATION*
+++ /dev/null
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.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.
- */
-
-#ifndef __ASM_BARRIER_H
-#define __ASM_BARRIER_H
-
-#ifndef __ASSEMBLY__
-
-/* TODO-vineetg: Need to see what this does, don't we need sync anywhere */
-#define mb() __asm__ __volatile__ ("" : : : "memory")
-#define rmb() mb()
-#define wmb() mb()
-#define set_mb(var, value) do { var = value; mb(); } while (0)
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
-#define read_barrier_depends() mb()
-
-/* TODO-vineetg verify the correctness of macros here */
-#ifdef CONFIG_SMP
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-#else
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#endif
-
-#define smp_read_barrier_depends() do { } while (0)
-
-#endif
-
-#endif
select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
select HAVE_ARCH_TRACEHOOK
select HAVE_BPF_JIT
+ select HAVE_CC_STACKPROTECTOR
select HAVE_CONTEXT_TRACKING
select HAVE_C_RECORDMCOUNT
- select HAVE_CC_STACKPROTECTOR
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_API_DEBUG
select HAVE_DMA_ATTRS
select ARM_HAS_SG_CHAIN
select ARM_PATCH_PHYS_VIRT
select AUTO_ZRELADDR
+ select CLKSRC_OF
select COMMON_CLK
select GENERIC_CLOCKEVENTS
select MULTI_IRQ_HANDLER
bool "Energy Micro efm32"
depends on !MMU
select ARCH_REQUIRE_GPIOLIB
- select AUTO_ZRELADDR
select ARM_NVIC
+ select AUTO_ZRELADDR
select CLKSRC_OF
select COMMON_CLK
select CPU_V7M
bool "IXP4xx-based"
depends on MMU
select ARCH_HAS_DMA_SET_COHERENT_MASK
- select ARCH_SUPPORTS_BIG_ENDIAN
select ARCH_REQUIRE_GPIOLIB
+ select ARCH_SUPPORTS_BIG_ENDIAN
select CLKSRC_MMIO
select CPU_XSCALE
select DMABOUNCE if PCI
default 8
config IWMMXT
- bool "Enable iWMMXt support" if !CPU_PJ4
- depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4
- default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4
+ bool "Enable iWMMXt support"
+ depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 || CPU_PJ4B
+ default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 || CPU_PJ4B
help
Enable support for iWMMXt context switching at run time if
running on a CPU that supports it.
config BL_SWITCHER
bool "big.LITTLE switcher support"
depends on BIG_LITTLE && MCPM && HOTPLUG_CPU
- select CPU_PM
select ARM_CPU_SUSPEND
+ select CPU_PM
help
The big.LITTLE "switcher" provides the core functionality to
transparently handle transition between a cluster of A15's
depends on CPU_V7 && !CPU_V6
depends on !GENERIC_ATOMIC64
depends on MMU
+ select ARCH_DMA_ADDR_T_64BIT
select ARM_PSCI
select SWIOTLB_XEN
- select ARCH_DMA_ADDR_T_64BIT
help
Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
default 0x40100000 if DEBUG_PXA_UART1
default 0x42000000 if ARCH_GEMINI
default 0x7c0003f8 if FOOTBRIDGE
- default 0x80230000 if DEBUG_PICOXCELL_UART
default 0x80070000 if DEBUG_IMX23_UART
default 0x80074000 if DEBUG_IMX28_UART
+ default 0x80230000 if DEBUG_PICOXCELL_UART
default 0x808c0000 if ARCH_EP93XX
default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX
default 0xfeb26000 if DEBUG_RK3X_UART1
default 0xfeb30c00 if DEBUG_KEYSTONE_UART0
default 0xfeb31000 if DEBUG_KEYSTONE_UART1
- default 0xfec12000 if DEBUG_MVEBU_UART || DEBUG_MVEBU_UART_ALTERNATE
- default 0xfed60000 if DEBUG_RK29_UART0
- default 0xfed64000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
- default 0xfed68000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
default 0xfec02000 if DEBUG_SOCFPGA_UART
+ default 0xfec12000 if DEBUG_MVEBU_UART || DEBUG_MVEBU_UART_ALTERNATE
default 0xfec20000 if DEBUG_DAVINCI_DMx_UART0
default 0xfed0c000 if DEBUG_DAVINCI_DA8XX_UART1
default 0xfed0d000 if DEBUG_DAVINCI_DA8XX_UART2
default 0xfed12000 if ARCH_KIRKWOOD
+ default 0xfed60000 if DEBUG_RK29_UART0
+ default 0xfed64000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
+ default 0xfed68000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
default 0xfedc0000 if ARCH_EP93XX
default 0xfee003f8 if FOOTBRIDGE
default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
- default 0xfef36000 if DEBUG_HIGHBANK_UART
default 0xfee82340 if ARCH_IOP13XX
default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
default 0xfef00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN
+ default 0xfef36000 if DEBUG_HIGHBANK_UART
default 0xfefff700 if ARCH_IOP33X
default 0xff003000 if DEBUG_U300_UART
default DEBUG_UART_PHYS if !MMU
dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
+dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb
dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm28155-ap.dtb \
bcm21664-garnet.dtb
-dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
-dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb
dtb-$(CONFIG_ARCH_BERLIN) += \
berlin2-sony-nsz-gs7.dtb \
berlin2cd-google-chromecast.dtb
omap3-sbc-t3730.dtb \
omap3-devkit8000.dtb \
omap3-beagle-xm.dtb \
+ omap3-beagle-xm-ab.dtb \
omap3-evm.dtb \
omap3-evm-37xx.dtb \
omap3-ldp.dtb \
dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \
qcom-msm8960-cdp.dtb \
qcom-apq8074-dragonboard.dtb
-dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
- ste-hrefprev60-stuib.dtb \
- ste-hrefprev60-tvk.dtb \
- ste-hrefv60plus-stuib.dtb \
- ste-hrefv60plus-tvk.dtb \
- ste-ccu8540.dtb \
- ste-ccu9540.dtb
dtb-$(CONFIG_ARCH_S3C24XX) += s3c2416-smdk2416.dtb
dtb-$(CONFIG_ARCH_S3C64XX) += s3c6410-mini6410.dtb \
s3c6410-smdk6410.dtb
tegra30-cardhu-a04.dtb \
tegra114-dalmore.dtb \
tegra124-venice2.dtb
+dtb-$(CONFIG_ARCH_U300) += ste-u300.dtb
+dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
+ ste-hrefprev60-stuib.dtb \
+ ste-hrefprev60-tvk.dtb \
+ ste-hrefv60plus-stuib.dtb \
+ ste-hrefv60plus-tvk.dtb \
+ ste-ccu8540.dtb \
+ ste-ccu9540.dtb
dtb-$(CONFIG_ARCH_VERSATILE) += versatile-ab.dtb \
versatile-pb.dtb
-dtb-$(CONFIG_ARCH_U300) += ste-u300.dtb
dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
vexpress-v2p-ca9.dtb \
vexpress-v2p-ca15-tc1.dtb \
&usb {
status = "okay";
- control@44e10000 {
+ control@44e10620 {
status = "okay";
};
dr_mode = "host";
};
- dma-controller@07402000 {
+ dma-controller@47402000 {
status = "okay";
};
};
am335x_evm_audio_pins: am335x_evm_audio_pins {
pinctrl-single,pins = <
- 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rx_dv.mcasp1_aclkx */
- 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_txd3.mcasp1_fsx */
+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */
+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */
0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */
0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
>;
&usb {
status = "okay";
- control@44e10000 {
+ control@44e10620 {
status = "okay";
};
dr_mode = "host";
};
- dma-controller@07402000 {
+ dma-controller@47402000 {
status = "okay";
};
};
&usb {
status = "okay";
- control@44e10000 {
+ control@44e10620 {
status = "okay";
};
dr_mode = "host";
};
- dma-controller@07402000 {
+ dma-controller@47402000 {
status = "okay";
};
};
reg = <0 0 0>; /* CS0, offset 0 */
nand-bus-width = <8>;
ti,nand-ecc-opt = "bch8";
- gpmc,device-nand = "true";
gpmc,device-width = <1>;
gpmc,sync-clk-ps = <0>;
gpmc,cs-on-ns = <0>;
&usb {
status = "okay";
- control@44e10000 {
+ control@44e10620 {
status = "okay";
};
dr_mode = "host";
};
- dma-controller@07402000 {
+ dma-controller@47402000 {
status = "okay";
};
};
};
/*
- * The soc node represents the soc top level view. It is uses for IPs
+ * The soc node represents the soc top level view. It is used for IPs
* that are not memory mapped in the MPU view or for the MPU itself.
*/
soc {
/*
* XXX: Use a flat representation of the AM33XX interconnect.
- * The real AM33XX interconnect network is quite complex.Since
- * that will not bring real advantage to represent that in DT
+ * The real AM33XX interconnect network is quite complex. Since
+ * it will not bring real advantage to represent that in DT
* for the moment, just use a fake OCP bus entry to represent
* the whole bus hierarchy.
*/
#size-cells = <0>;
compatible = "marvell,orion-mdio";
reg = <0x72004 0x4>;
+ clocks = <&gateclk 4>;
};
eth1: ethernet@74000 {
#size-cells = <0>;
compatible = "marvell,orion-mdio";
reg = <0x72004 0x4>;
+ clocks = <&gateclk 4>;
};
coredivclk: clock@e4250 {
};
/*
- * The soc node represents the soc top level view. It is uses for IPs
+ * The soc node represents the soc top level view. It is used for IPs
* that are not memory mapped in the MPU view or for the MPU itself.
*/
soc {
/*
* XXX: Use a flat representation of the SOC interconnect.
* The real OMAP interconnect network is quite complex.
- * Since that will not bring real advantage to represent that in DT for
+ * Since it will not bring real advantage to represent that in DT for
* the moment, just use a fake OCP bus entry to represent the whole bus
* hierarchy.
*/
#clock-cells = <0>;
compatible = "ti,mux-clock";
clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>;
- ti,bit-shift = <28>;
+ ti,bit-shift = <24>;
reg = <0x1860>;
};
osc {
compatible = "fsl,imx-osc", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <24000000>;
};
};
osc26m {
compatible = "fsl,imx-osc26m", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <0>;
};
};
osc26m {
compatible = "fsl,imx-osc26m", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <26000000>;
};
};
ckil {
compatible = "fsl,imx-ckil", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <32768>;
};
ckih1 {
compatible = "fsl,imx-ckih1", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <22579200>;
};
ckih2 {
compatible = "fsl,imx-ckih2", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <0>;
};
osc {
compatible = "fsl,imx-osc", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <24000000>;
};
};
ckil {
compatible = "fsl,imx-ckil", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <32768>;
};
ckih1 {
compatible = "fsl,imx-ckih1", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <0>;
};
ckih2 {
compatible = "fsl,imx-ckih2", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <0>;
};
osc {
compatible = "fsl,imx-osc", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <24000000>;
};
};
compatible = "denx,imx53-m53evk", "fsl,imx53";
memory {
- reg = <0x70000000 0x20000000>;
+ reg = <0x70000000 0x20000000>,
+ <0xb0000000 0x20000000>;
};
soc {
irq-trigger = <0x1>;
stmpe_touchscreen {
- compatible = "stmpe,ts";
+ compatible = "st,stmpe-ts";
reg = <0>;
- ts,sample-time = <4>;
- ts,mod-12b = <1>;
- ts,ref-sel = <0>;
- ts,adc-freq = <1>;
- ts,ave-ctrl = <3>;
- ts,touch-det-delay = <3>;
- ts,settling = <4>;
- ts,fraction-z = <7>;
- ts,i-drive = <1>;
+ st,sample-time = <4>;
+ st,mod-12b = <1>;
+ st,ref-sel = <0>;
+ st,adc-freq = <1>;
+ st,ave-ctrl = <3>;
+ st,touch-det-delay = <3>;
+ st,settling = <4>;
+ st,fraction-z = <7>;
+ st,i-drive = <1>;
};
};
/ {
memory {
- reg = <0x70000000 0x40000000>;
+ reg = <0x70000000 0x20000000>,
+ <0xb0000000 0x20000000>;
};
display0: display@di0 {
soc {
display: display@di0 {
compatible = "fsl,imx-parallel-display";
- crtcs = <&ipu 0>;
interface-pix-fmt = "rgb24";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_rgb24_vga1>;
status = "okay";
+ port {
+ display0_in: endpoint {
+ remote-endpoint = <&ipu_di0_disp0>;
+ };
+ };
+
display-timings {
VGA {
clock-frequency = <25200000>;
};
};
+&ipu_di0_disp0 {
+ remote-endpoint = <&display0_in>;
+};
+
&kpp {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_kpp>;
ckil {
compatible = "fsl,imx-ckil", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <32768>;
};
ckih1 {
compatible = "fsl,imx-ckih1", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <22579200>;
};
ckih2 {
compatible = "fsl,imx-ckih2", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <0>;
};
osc {
compatible = "fsl,imx-osc", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <24000000>;
};
};
port {
lvds1_in: endpoint {
- remote-endpoint = <&ipu_di0_lvds0>;
+ remote-endpoint = <&ipu_di1_lvds1>;
};
};
};
compatible = "dmo,imx6q-edmqmx6", "fsl,imx6q";
aliases {
- gpio7 = &stmpe_gpio;
+ gpio7 = &stmpe_gpio1;
+ gpio8 = &stmpe_gpio2;
+ stmpe-i2c0 = &stmpe1;
+ stmpe-i2c1 = &stmpe2;
};
memory {
regulator-always-on;
};
- reg_usb_otg_vbus: regulator@1 {
+ reg_usb_otg_switch: regulator@1 {
compatible = "regulator-fixed";
reg = <1>;
- regulator-name = "usb_otg_vbus";
+ regulator-name = "usb_otg_switch";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio7 12 0>;
+ regulator-boot-on;
+ regulator-always-on;
};
reg_usb_host1: regulator@2 {
led-blue {
label = "blue";
- gpios = <&stmpe_gpio 8 GPIO_ACTIVE_HIGH>;
+ gpios = <&stmpe_gpio1 8 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
led-green {
label = "green";
- gpios = <&stmpe_gpio 9 GPIO_ACTIVE_HIGH>;
+ gpios = <&stmpe_gpio1 9 GPIO_ACTIVE_HIGH>;
};
led-pink {
label = "pink";
- gpios = <&stmpe_gpio 10 GPIO_ACTIVE_HIGH>;
+ gpios = <&stmpe_gpio1 10 GPIO_ACTIVE_HIGH>;
};
led-red {
label = "red";
- gpios = <&stmpe_gpio 11 GPIO_ACTIVE_HIGH>;
+ gpios = <&stmpe_gpio1 11 GPIO_ACTIVE_HIGH>;
};
};
};
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2
- &pinctrl_stmpe>;
+ &pinctrl_stmpe1
+ &pinctrl_stmpe2>;
status = "okay";
pmic: pfuze100@08 {
};
};
- stmpe: stmpe1601@40 {
+ stmpe1: stmpe1601@40 {
compatible = "st,stmpe1601";
reg = <0x40>;
interrupts = <30 0>;
interrupt-parent = <&gpio3>;
- stmpe_gpio: stmpe_gpio {
+ stmpe_gpio1: stmpe_gpio {
+ #gpio-cells = <2>;
+ compatible = "st,stmpe-gpio";
+ };
+ };
+
+ stmpe2: stmpe1601@44 {
+ compatible = "st,stmpe1601";
+ reg = <0x44>;
+ interrupts = <2 0>;
+ interrupt-parent = <&gpio5>;
+
+ stmpe_gpio2: stmpe_gpio {
#gpio-cells = <2>;
compatible = "st,stmpe-gpio";
};
>;
};
- pinctrl_stmpe: stmpegrp {
+ pinctrl_stmpe1: stmpe1grp {
fsl,pins = <MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x80000000>;
};
+ pinctrl_stmpe2: stmpe2grp {
+ fsl,pins = <MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x80000000>;
+ };
+
pinctrl_uart1: uart1grp {
fsl,pins = <
MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
pinctrl_usbotg: usbotggrp {
fsl,pins = <
- MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
+ MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
>;
};
&usbh1 {
vbus-supply = <®_usb_host1>;
disable-over-current;
+ dr_mode = "host";
status = "okay";
};
&usbotg {
- vbus-supply = <®_usb_otg_vbus>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotg>;
disable-over-current;
&ldb {
status = "okay";
- lvds-channel@0 {
- crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
- };
};
&pcie {
&ldb {
status = "okay";
- lvds-channel@0 {
- crtcs = <&ipu1 0>, <&ipu1 1>;
- };
};
&pcie {
/* GPIO16 -> AR8035 25MHz */
MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0xc0000000
MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x80000000
- MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
- MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
- MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
- MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
- MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b030
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b030
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b030
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b030
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b030
/* AR8035 CLK_25M --> ENET_REF_CLK (V22) */
MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x0a0b1
/* AR8035 pin strapping: IO voltage: pull up */
- MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030
/* AR8035 pin strapping: PHYADDR#0: pull down */
- MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x130b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x13030
/* AR8035 pin strapping: PHYADDR#1: pull down */
- MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x130b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x13030
/* AR8035 pin strapping: MODE#1: pull up */
- MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030
/* AR8035 pin strapping: MODE#3: pull up */
- MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030
/* AR8035 pin strapping: MODE#0: pull down */
- MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x130b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x13030
/*
* As the RMII pins are also connected to RGMII
* http://www.gnu.org/copyleft/gpl.html
*/
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
#include "skeleton.dtsi"
/ {
intc: interrupt-controller@00a01000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
- #address-cells = <1>;
- #size-cells = <1>;
interrupt-controller;
reg = <0x00a01000 0x1000>,
<0x00a00100 0x100>;
ckil {
compatible = "fsl,imx-ckil", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <32768>;
};
ckih1 {
compatible = "fsl,imx-ckih1", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <0>;
};
osc {
compatible = "fsl,imx-osc", "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <24000000>;
};
};
0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
num-lanes = <1>;
interrupts = <0 123 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
status = "disabled";
MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
+ MX6SL_PAD_ECSPI1_SS0__GPIO4_IO11 0x80000000
>;
};
intc: interrupt-controller@00a01000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
- #address-cells = <1>;
- #size-cells = <1>;
interrupt-controller;
reg = <0x00a01000 0x1000>,
<0x00a00100 0x100>;
ckil {
compatible = "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <32768>;
};
osc {
compatible = "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <24000000>;
};
};
m25p16@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "m25p16";
+ compatible = "st,m25p16";
reg = <0>;
spi-max-frequency = <40000000>;
mode = <0>;
flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "mx25l4005a";
+ compatible = "mxicy,mx25l4005a";
reg = <0>;
spi-max-frequency = <20000000>;
mode = <0>;
m25p40@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "mx25l1606e";
+ compatible = "mxicy,mx25l1606e";
reg = <0>;
spi-max-frequency = <50000000>;
mode = <0>;
status = "okay";
eeprom@50 {
- compatible = "at,24c04";
+ compatible = "atmel,24c04";
pagesize = <16>;
reg = <0x50>;
};
flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "mx25l12805d";
+ compatible = "mxicy,mx25l12805d";
reg = <0>;
spi-max-frequency = <50000000>;
mode = <0>;
flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "mx25l4005a";
+ compatible = "mxicy,mx25l4005a";
reg = <0>;
spi-max-frequency = <20000000>;
mode = <0>;
status = "okay";
eeprom@50 {
- compatible = "at,24c04";
+ compatible = "atmel,24c04";
pagesize = <16>;
reg = <0x50>;
};
status = "okay";
adt7476: adt7476a@2e {
- compatible = "adt7476";
+ compatible = "adi,adt7476";
reg = <0x2e>;
};
};
status = "okay";
lm85: lm85@2e {
- compatible = "lm85";
+ compatible = "national,lm85";
reg = <0x2e>;
};
};
pinctrl-names = "default";
s35390a: s35390a@30 {
- compatible = "s35390a";
+ compatible = "sii,s35390a";
reg = <0x30>;
};
};
pinctrl-names = "default";
s24c02: s24c02@50 {
- compatible = "24c02";
+ compatible = "atmel,24c02";
reg = <0x50>;
};
};
--- /dev/null
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.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.
+ */
+
+#include "omap3-beagle-xm.dts"
+
+/ {
+ /* HS USB Port 2 Power enable was inverted with the xM C */
+ hsusb2_power: hsusb2_power_reg {
+ enable-active-high;
+ };
+};
reg = <0 0 0>; /* CS0, offset 0 */
nand-bus-width = <16>;
- gpmc,device-nand;
gpmc,sync-clk-ps = <0>;
gpmc,cs-on-ns = <0>;
gpmc,cs-rd-off-ns = <44>;
/* no elm on omap3 */
gpmc,mux-add-data = <0>;
- gpmc,device-nand;
gpmc,device-width = <2>;
gpmc,wait-pin = <0>;
gpmc,wait-monitoring-ns = <0>;
/*
* XXX: Use a flat representation of the OMAP3 interconnect.
* The real OMAP interconnect network is quite complex.
- * Since that will not bring real advantage to represent that in DT for
+ * Since it will not bring real advantage to represent that in DT for
* the moment, just use a fake OCP bus entry to represent the whole bus
* hierarchy.
*/
};
/*
- * The soc node represents the soc top level view. It is uses for IPs
+ * The soc node represents the soc top level view. It is used for IPs
* that are not memory mapped in the MPU view or for the MPU itself.
*/
soc {
/*
* XXX: Use a flat representation of the OMAP4 interconnect.
* The real OMAP interconnect network is quite complex.
- * Since that will not bring real advantage to represent that in DT for
+ * Since it will not bring real advantage to represent that in DT for
* the moment, just use a fake OCP bus entry to represent the whole bus
* hierarchy.
*/
};
/*
- * The soc node represents the soc top level view. It is uses for IPs
+ * The soc node represents the soc top level view. It is used for IPs
* that are not memory mapped in the MPU view or for the MPU itself.
*/
soc {
/*
* XXX: Use a flat representation of the OMAP3 interconnect.
* The real OMAP interconnect network is quite complex.
- * Since that will not bring real advantage to represent that in DT for
+ * Since it will not bring real advantage to represent that in DT for
* the moment, just use a fake OCP bus entry to represent the whole bus
* hierarchy.
*/
<0x4a084c00 0x40>;
reg-names = "phy_rx", "phy_tx", "pll_ctrl";
ctrl-module = <&omap_control_usb3phy>;
+ clocks = <&usb_phy_cm_clk32k>,
+ <&sys_clkin>,
+ <&usb_otg_ss_refclk960m>;
+ clock-names = "wkupclk",
+ "sysclk",
+ "refclk";
#phy-cells = <0>;
};
};
gic: interrupt-controller@c2800000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
- #address-cells = <1>;
interrupt-controller;
reg = <0xc2800000 0x1000>,
<0xc2000000 0x1000>;
};
sdhi0_pins: sd0 {
- renesas,gpios = "sdhi0_data4", "sdhi0_ctrl";
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl";
renesas,function = "sdhi0";
};
sdhi2_pins: sd2 {
- renesas,gpios = "sdhi2_data4", "sdhi2_ctrl";
+ renesas,groups = "sdhi2_data4", "sdhi2_ctrl";
renesas,function = "sdhi2";
};
};
sdhi0_pins: sd0 {
- renesas,gpios = "sdhi0_data4", "sdhi0_ctrl";
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl";
renesas,function = "sdhi0";
};
sdhi1_pins: sd1 {
- renesas,gpios = "sdhi1_data4", "sdhi1_ctrl";
+ renesas,groups = "sdhi1_data4", "sdhi1_ctrl";
renesas,function = "sdhi1";
};
sdhi2_pins: sd2 {
- renesas,gpios = "sdhi2_data4", "sdhi2_ctrl";
+ renesas,groups = "sdhi2_data4", "sdhi2_ctrl";
renesas,function = "sdhi2";
};
uart0 {
uart0_xfer: uart0-xfer {
- rockchip,pins = <RK_GPIO1 0 RK_FUNC_1 &pcfg_pull_none>,
+ rockchip,pins = <RK_GPIO1 0 RK_FUNC_1 &pcfg_pull_up>,
<RK_GPIO1 1 RK_FUNC_1 &pcfg_pull_none>;
};
uart1 {
uart1_xfer: uart1-xfer {
- rockchip,pins = <RK_GPIO1 4 RK_FUNC_1 &pcfg_pull_none>,
+ rockchip,pins = <RK_GPIO1 4 RK_FUNC_1 &pcfg_pull_up>,
<RK_GPIO1 5 RK_FUNC_1 &pcfg_pull_none>;
};
uart2 {
uart2_xfer: uart2-xfer {
- rockchip,pins = <RK_GPIO1 8 RK_FUNC_1 &pcfg_pull_none>,
+ rockchip,pins = <RK_GPIO1 8 RK_FUNC_1 &pcfg_pull_up>,
<RK_GPIO1 9 RK_FUNC_1 &pcfg_pull_none>;
};
/* no rts / cts for uart2 */
uart3 {
uart3_xfer: uart3-xfer {
- rockchip,pins = <RK_GPIO1 10 RK_FUNC_1 &pcfg_pull_none>,
+ rockchip,pins = <RK_GPIO1 10 RK_FUNC_1 &pcfg_pull_up>,
<RK_GPIO1 11 RK_FUNC_1 &pcfg_pull_none>;
};
gic: interrupt-controller@f0001000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
- #address-cells = <1>;
interrupt-controller;
reg = <0xf0001000 0x1000>,
<0xf0000100 0x100>;
/*
* DTS file for SPEAr320 Evaluation Baord
*
- * Copyright 2012 Shiraz Hashim <shiraz.hashim@st.com>
+ * Copyright 2012 Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
status = "disabled";
};
- serial@0,70006400 {
- compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart";
- reg = <0x0 0x70006400 0x0 0x40>;
- reg-shift = <2>;
- interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA124_CLK_UARTE>;
- resets = <&tegra_car 66>;
- reset-names = "serial";
- dmas = <&apbdma 20>, <&apbdma 20>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
pwm@0,7000a000 {
compatible = "nvidia,tegra124-pwm", "nvidia,tegra20-pwm";
reg = <0x0 0x7000a000 0x0 0x100>;
clocks {
audio_ext {
compatible = "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <24576000>;
};
enet_ext {
compatible = "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <50000000>;
};
};
sxosc {
compatible = "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <32768>;
};
fxosc {
compatible = "fixed-clock";
+ #clock-cells = <0>;
clock-frequency = <24000000>;
};
};
intc: interrupt-controller@40002000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
- #address-cells = <1>;
- #size-cells = <1>;
interrupt-controller;
reg = <0x40003000 0x1000>,
<0x40002100 0x100>;
device_type = "cpu";
reg = <0>;
clocks = <&clkc 3>;
+ clock-latency = <1000>;
operating-points = <
/* kHz uV */
666667 1000000
interrupt-parent = <&intc>;
ranges;
+ i2c0: zynq-i2c@e0004000 {
+ compatible = "cdns,i2c-r1p10";
+ status = "disabled";
+ clocks = <&clkc 38>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 25 4>;
+ reg = <0xe0004000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ i2c1: zynq-i2c@e0005000 {
+ compatible = "cdns,i2c-r1p10";
+ status = "disabled";
+ clocks = <&clkc 39>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 48 4>;
+ reg = <0xe0005000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
intc: interrupt-controller@f8f01000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
phy-mode = "rgmii";
};
+&i2c0 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ i2cswitch@74 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x74>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ si570: clock-generator@5d {
+ #clock-cells = <0>;
+ compatible = "silabs,si570";
+ temperature-stability = <50>;
+ reg = <0x5d>;
+ factory-fout = <156250000>;
+ clock-frequency = <148500000>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ eeprom@54 {
+ compatible = "at,24c08";
+ reg = <0x54>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ gpio@21 {
+ compatible = "ti,tca6416";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+
+ i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ hwmon@52 {
+ compatible = "ti,ucd9248";
+ reg = <52>;
+ };
+ hwmon@53 {
+ compatible = "ti,ucd9248";
+ reg = <53>;
+ };
+ hwmon@54 {
+ compatible = "ti,ucd9248";
+ reg = <54>;
+ };
+ };
+ };
+};
+
&sdhci0 {
status = "okay";
};
phy-mode = "rgmii";
};
+&i2c0 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ i2cswitch@74 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x74>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ si570: clock-generator@5d {
+ #clock-cells = <0>;
+ compatible = "silabs,si570";
+ temperature-stability = <50>;
+ reg = <0x5d>;
+ factory-fout = <156250000>;
+ clock-frequency = <148500000>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ eeprom@54 {
+ compatible = "at,24c08";
+ reg = <0x54>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ gpio@21 {
+ compatible = "ti,tca6416";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+
+ i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ ucd90120@65 {
+ compatible = "ti,ucd90120";
+ reg = <0x65>;
+ };
+ };
+ };
+};
+
&sdhci0 {
status = "okay";
};
{
int ret;
- if (MAX_NR_CLUSTERS != 2) {
- pr_err("%s: only dual cluster systems are supported\n", __func__);
- return -EINVAL;
- }
+ if (!mcpm_is_available())
+ return -ENODEV;
cpu_notifier(bL_switcher_hotplug_callback, 0);
return 0;
}
+bool mcpm_is_available(void)
+{
+ return (platform_ops) ? true : false;
+}
+
int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster)
{
if (!platform_ops)
CONFIG_CRC7=y
CONFIG_XZ_DEC=y
CONFIG_AVERAGE=y
-CONFIG_PINCTRL_CAPRI=y
+CONFIG_PINCTRL_BCM281XX=y
CONFIG_WATCHDOG=y
CONFIG_BCM_KONA_WDT=y
CONFIG_BCM_KONA_WDT_DEBUG=y
CONFIG_USB_TEST=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_OMAP_USB2=y
-CONFIG_OMAP_USB3=y
+CONFIG_TI_PIPE3=y
CONFIG_AM335X_PHY_USB=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
# CONFIG_IOSCHED_CFQ is not set
# CONFIG_ARCH_MULTI_V7 is not set
CONFIG_ARCH_U300=y
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="root=/dev/ram0 rw rootfstype=rootfs console=ttyAMA0,115200n8 lpj=515072"
CONFIG_CPU_IDLE=y
-CONFIG_FPE_NWFPE=y
# CONFIG_SUSPEND is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_FS=y
# CONFIG_SCHED_DEBUG is not set
CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_INFO=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
-CONFIG_NO_HZ=y
+CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_KALLSYMS_ALL=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_U8500=y
CONFIG_MACH_HREFV60=y
CONFIG_MACH_SNOWBALL=y
-CONFIG_MACH_UX500_DT=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
CONFIG_PREEMPT=y
CONFIG_IP_PNP_DHCP=y
CONFIG_NETFILTER=y
CONFIG_PHONET=y
-# CONFIG_WIRELESS is not set
+CONFIG_CFG80211=y
+CONFIG_CFG80211_DEBUGFS=y
+CONFIG_MAC80211=y
+CONFIG_MAC80211_LEDS=y
CONFIG_CAIF=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=65536
CONFIG_SENSORS_BH1780=y
CONFIG_NETDEVICES=y
CONFIG_SMSC911X=y
CONFIG_SMSC_PHY=y
-# CONFIG_WLAN is not set
+CONFIG_CW1200=y
+CONFIG_CW1200_WLAN_SDIO=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_KEYBOARD_ATKBD is not set
CONFIG_USB_GADGET=y
CONFIG_USB_ETH=m
CONFIG_MMC=y
-CONFIG_MMC_UNSAFE_RESUME=y
-# CONFIG_MMC_BLOCK_BOUNCE is not set
CONFIG_MMC_ARMMMCI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_LM3530=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_LP5521=y
-CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_AB8500=y
CONFIG_STAGING=y
CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
CONFIG_HSEM_U8500=y
+CONFIG_IIO=y
+CONFIG_IIO_ST_ACCEL_3AXIS=y
+CONFIG_IIO_ST_GYRO_3AXIS=y
+CONFIG_IIO_ST_MAGN_3AXIS=y
+CONFIG_IIO_ST_PRESS=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT3_FS=y
CONFIG_EXT4_FS=y
CONFIG_VFAT_FS=y
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_MISC_FILESYSTEMS is not set
#endif
/*
- * Marvell's PJ4 core is based on V7 version. It has some modification
- * for coprocessor setting. For this reason, we need a way to distinguish
- * it.
+ * Marvell's PJ4 and PJ4B cores are based on V7 version,
+ * but require a specical sequence for enabling coprocessors.
+ * For this reason, we need a way to distinguish them.
*/
-#ifndef CONFIG_CPU_PJ4
-#define cpu_is_pj4() 0
-#else
+#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
static inline int cpu_is_pj4(void)
{
unsigned int id;
id = read_cpuid_id();
- if ((id & 0xfffffff0) == 0x562f5840)
+ if ((id & 0xff0fff00) == 0x560f5800)
return 1;
return 0;
}
+#else
+#define cpu_is_pj4() 0
#endif
#endif
/* Select the best insn combination to perform the */ \
/* actual __m * __n / (__p << 64) operation. */ \
if (!__c) { \
- asm ( "umull %Q0, %R0, %1, %Q2\n\t" \
+ asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" \
"mov %Q0, #0" \
: "=&r" (__res) \
: "r" (__m), "r" (__n) \
* CPU/cluster power operations API for higher subsystems to use.
*/
+/**
+ * mcpm_is_available - returns whether MCPM is initialized and available
+ *
+ * This returns true or false accordingly.
+ */
+bool mcpm_is_available(void);
+
/**
* mcpm_cpu_power_up - make given CPU in given cluster runable
*
}
}
-static inline void tlb_flush_mmu(struct mmu_gather *tlb)
+static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
{
tlb_flush(tlb);
+}
+
+static inline void tlb_flush_mmu_free(struct mmu_gather *tlb)
+{
free_pages_and_swap_cache(tlb->pages, tlb->nr);
tlb->nr = 0;
if (tlb->pages == tlb->local)
__tlb_alloc_page(tlb);
}
+static inline void tlb_flush_mmu(struct mmu_gather *tlb)
+{
+ tlb_flush_mmu_tlbonly(tlb);
+ tlb_flush_mmu_free(tlb);
+}
+
static inline void
tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
{
#define __NR_finit_module (__NR_SYSCALL_BASE+379)
#define __NR_sched_setattr (__NR_SYSCALL_BASE+380)
#define __NR_sched_getattr (__NR_SYSCALL_BASE+381)
+#define __NR_renameat2 (__NR_SYSCALL_BASE+382)
/*
* This may need to be greater than __NR_last_syscall+1 in order to
obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o
+obj-$(CONFIG_CPU_PJ4B) += pj4-cp0.o
obj-$(CONFIG_IWMMXT) += iwmmxt.o
obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o
CALL(sys_finit_module)
/* 380 */ CALL(sys_sched_setattr)
CALL(sys_sched_getattr)
+ CALL(sys_renameat2)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
add r6, r6, r3 @ adjust __pv_phys_pfn_offset address
add r7, r7, r3 @ adjust __pv_offset address
mov r0, r8, lsr #12 @ convert to PFN
- str r0, [r6, #LOW_OFFSET] @ save computed PHYS_OFFSET to __pv_phys_pfn_offset
+ str r0, [r6] @ save computed PHYS_OFFSET to __pv_phys_pfn_offset
strcc ip, [r7, #HIGH_OFFSET] @ save to __pv_offset high bits
mov r6, r3, lsr #24 @ constant for add/sub instructions
teq r3, r6, lsl #24 @ must be 16MiB aligned
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
-#if defined(CONFIG_CPU_PJ4)
+#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
#define PJ4(code...) code
#define XSC(code...)
-#else
+#elif defined(CONFIG_CPU_MOHAWK) || \
+ defined(CONFIG_CPU_XSC3) || \
+ defined(CONFIG_CPU_XSCALE)
#define PJ4(code...)
#define XSC(code...) code
+#else
+#error "Unsupported iWMMXt architecture"
#endif
#define MMX_WR0 (0x00)
soft_restart(reboot_entry_phys);
}
+
+void arch_crash_save_vmcoreinfo(void)
+{
+#ifdef CONFIG_ARM_LPAE
+ VMCOREINFO_CONFIG(ARM_LPAE);
+#endif
+}
return NOTIFY_DONE;
}
-static struct notifier_block iwmmxt_notifier_block = {
+static struct notifier_block __maybe_unused iwmmxt_notifier_block = {
.notifier_call = iwmmxt_do,
};
: "=r" (temp) : "r" (value));
}
+static int __init pj4_get_iwmmxt_version(void)
+{
+ u32 cp_access, wcid;
+
+ cp_access = pj4_cp_access_read();
+ pj4_cp_access_write(cp_access | 0xf);
+
+ /* check if coprocessor 0 and 1 are available */
+ if ((pj4_cp_access_read() & 0xf) != 0xf) {
+ pj4_cp_access_write(cp_access);
+ return -ENODEV;
+ }
+
+ /* read iWMMXt coprocessor id register p1, c0 */
+ __asm__ __volatile__ ("mrc p1, 0, %0, c0, c0, 0\n" : "=r" (wcid));
+
+ pj4_cp_access_write(cp_access);
+
+ /* iWMMXt v1 */
+ if ((wcid & 0xffffff00) == 0x56051000)
+ return 1;
+ /* iWMMXt v2 */
+ if ((wcid & 0xffffff00) == 0x56052000)
+ return 2;
+
+ return -EINVAL;
+}
/*
* Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
*/
static int __init pj4_cp0_init(void)
{
- u32 cp_access;
+ u32 __maybe_unused cp_access;
+ int vers;
if (!cpu_is_pj4())
return 0;
+ vers = pj4_get_iwmmxt_version();
+ if (vers < 0)
+ return 0;
+
+#ifndef CONFIG_IWMMXT
+ pr_info("PJ4 iWMMXt coprocessor detected, but kernel support is missing.\n");
+#else
cp_access = pj4_cp_access_read() & ~0xf;
pj4_cp_access_write(cp_access);
- printk(KERN_INFO "PJ4 iWMMXt coprocessor enabled.\n");
+ pr_info("PJ4 iWMMXt v%d coprocessor enabled.\n", vers);
elf_hwcap |= HWCAP_IWMMXT;
thread_register_notifier(&iwmmxt_notifier_block);
+#endif
return 0;
}
int ret;
switch (cmd) {
- case F_GETLKP:
- case F_SETLKP:
- case F_SETLKPW:
+ case F_OFD_GETLK:
+ case F_OFD_SETLK:
+ case F_OFD_SETLKW:
case F_GETLK64:
case F_SETLK64:
case F_SETLKW64:
};
static struct platform_device at91_adc_device = {
- .name = "at91_adc",
+ .name = "at91sam9260-adc",
.id = -1,
.dev = {
.platform_data = &adc_data,
};
static struct platform_device at91_adc_device = {
- .name = "at91_adc",
+ .name = "at91sam9g45-adc",
.id = -1,
.dev = {
.platform_data = &adc_data,
* the "output_enable" bit as a gate, even though it's really just
* enabling clock output.
*/
- clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "dummy", base + 0x160, 10);
- clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "dummy", base + 0x160, 11);
+ clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "lvds1_sel", base + 0x160, 10);
+ clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "lvds2_sel", base + 0x160, 11);
/* name parent_name reg idx */
clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
- clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
- clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
- clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
- clk[ipu2_di1_pre_sel] = imx_clk_mux("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
- clk[ipu1_di0_sel] = imx_clk_mux("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels));
- clk[ipu1_di1_sel] = imx_clk_mux("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels));
- clk[ipu2_di0_sel] = imx_clk_mux("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels));
- clk[ipu2_di1_sel] = imx_clk_mux("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels));
+ clk[ipu1_di0_pre_sel] = imx_clk_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
+ clk[ipu1_di1_pre_sel] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
+ clk[ipu2_di0_pre_sel] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
+ clk[ipu2_di1_pre_sel] = imx_clk_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
+ clk[ipu1_di0_sel] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT);
+ clk[ipu1_di1_sel] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT);
+ clk[ipu2_di0_sel] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT);
+ clk[ipu2_di1_sel] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT);
clk[hsi_tx_sel] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels));
clk[pcie_axi_sel] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
clk[ssi1_sel] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
}
+ clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]);
+ clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]);
+ clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]);
+ clk_set_parent(clk[ipu2_di1_pre_sel], clk[pll5_video_div]);
+ clk_set_parent(clk[ipu1_di0_sel], clk[ipu1_di0_pre]);
+ clk_set_parent(clk[ipu1_di1_sel], clk[ipu1_di1_pre]);
+ clk_set_parent(clk[ipu2_di0_sel], clk[ipu2_di0_pre]);
+ clk_set_parent(clk[ipu2_di1_sel], clk[ipu2_di1_pre]);
+
/*
* The gpmi needs 100MHz frequency in the EDO/Sync mode,
* We can not get the 100MHz from the pll2_pfd0_352m.
static int __init rx51_video_init(void)
{
- if (!machine_is_nokia_rx51() && !of_machine_is_compatible("nokia,omap3-n900"))
+ if (!machine_is_nokia_rx51())
return 0;
if (omap_mux_init_gpio(RX51_LCD_RESET_GPIO, OMAP_PIN_OUTPUT)) {
if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
v == OMAP3XXX_EN_DPLL_FRBYPASS)
return 1;
- } else if (soc_is_am33xx() || cpu_is_omap44xx()) {
+ } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) {
if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
v == OMAP4XXX_EN_DPLL_FRBYPASS ||
v == OMAP4XXX_EN_DPLL_MNBYPASS)
if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
v == OMAP3XXX_EN_DPLL_FRBYPASS)
return __clk_get_rate(dd->clk_bypass);
- } else if (soc_is_am33xx() || cpu_is_omap44xx()) {
+ } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) {
if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
v == OMAP4XXX_EN_DPLL_FRBYPASS ||
v == OMAP4XXX_EN_DPLL_MNBYPASS)
int r;
spin_lock(&gpmc_mem_lock);
- r = release_resource(&gpmc_cs_mem[cs]);
+ r = release_resource(res);
res->start = 0;
res->end = 0;
spin_unlock(&gpmc_mem_lock);
pr_err("%s: requested chip-select is disabled\n", __func__);
return -ENODEV;
}
+
+ /*
+ * Make sure we ignore any device offsets from the GPMC partition
+ * allocated for the chip select and that the new base confirms
+ * to the GPMC 16MB minimum granularity.
+ */
+ base &= ~(SZ_16M - 1);
+
gpmc_cs_get_memconf(cs, &old_base, &size);
if (base == old_base)
return 0;
void gpmc_cs_free(int cs)
{
+ struct resource *res = &gpmc_cs_mem[cs];
+
spin_lock(&gpmc_mem_lock);
if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) {
printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs);
return;
}
gpmc_cs_disable_mem(cs);
- release_resource(&gpmc_cs_mem[cs]);
+ if (res->flags)
+ release_resource(res);
gpmc_cs_set_reserved(cs, 0);
spin_unlock(&gpmc_mem_lock);
}
return -EINVAL;
}
- if (np)
+ if (np) {
if (of_find_property(np, "ti,no-reset-on-init", NULL))
oh->flags |= HWMOD_INIT_NO_RESET;
if (of_find_property(np, "ti,no-idle-on-init", NULL))
oh->flags |= HWMOD_INIT_NO_IDLE;
+ }
oh->_state = _HWMOD_STATE_INITIALIZED;
static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = {
.name = "usb_host_hs",
.class = &omap3xxx_usb_host_hs_hwmod_class,
- .clkdm_name = "l3_init_clkdm",
+ .clkdm_name = "usbhost_clkdm",
.mpu_irqs = omap3xxx_usb_host_hs_irqs,
.main_clk = "usbhost_48m_fck",
.prcm = {
static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = {
.name = "usb_tll_hs",
.class = &omap3xxx_usb_tll_hs_hwmod_class,
- .clkdm_name = "l3_init_clkdm",
+ .clkdm_name = "core_l4_clkdm",
.mpu_irqs = omap3xxx_usb_tll_hs_irqs,
.main_clk = "usbtll_fck",
.prcm = {
omap3_sram_restore_context();
omap2_sms_restore_context();
}
- if (core_next_state == PWRDM_POWER_OFF)
- omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
- OMAP3430_GR_MOD,
- OMAP3_PRM_VOLTCTRL_OFFSET);
}
omap3_intc_resume_idle();
#include <linux/gpio.h>
#include <linux/mfd/asic3.h>
+#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */
#define HX4700_ASIC3_GPIO_BASE PXA_NR_BUILTIN_GPIO
#define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS)
node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu");
if (!node) {
- pr_err("%s: could not find sram dt node\n", __func__);
+ pr_err("%s: could not find pmu dt node\n", __func__);
return;
}
.platform = "sh_fsi2",
.daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM,
.cpu_dai = {
+ .fmt = SND_SOC_DAIFMT_IB_NF,
.name = "fsia-dai",
},
.codec_dai = {
.card = "SSI01-AK4643",
.codec = "ak4642-codec.2-0012",
.platform = "rcar_sound",
- .daifmt = SND_SOC_DAIFMT_LEFT_J,
+ .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM,
.cpu_dai = {
.name = "rcar_sound",
- .fmt = SND_SOC_DAIFMT_CBS_CFS,
},
.codec_dai = {
.name = "ak4642-hifi",
- .fmt = SND_SOC_DAIFMT_CBM_CFM,
.sysclk = 11289600,
},
};
[MSTP010] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 10, 0), /* SSI2 */
[MSTP009] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 9, 0), /* SSI3 */
[MSTP008] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 8, 0), /* SRU */
- [MSTP007] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 7, 0), /* HSPI */
+ [MSTP007] = SH_CLK_MSTP32(&s_clk, MSTPCR0, 7, 0), /* HSPI */
};
static struct clk_lookup lookups[] = {
*
* Picked from realview
* Copyright (c) 2012 ST Microelectronics Limited
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@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
* based upon linux/arch/arm/mach-realview/platsmp.c
*
* Copyright (C) 2012 ST Microelectronics Ltd.
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@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
* arch/arm/plat-spear/time.c
*
* Copyright (C) 2010 ST Microelectronics
- * Shiraz Hashim<shiraz.hashim@st.com>
+ * Shiraz Hashim<shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
static int clockevent_next_event(unsigned long evt,
struct clock_event_device *clk_event_dev);
-static void spear_clocksource_init(void)
+static void __init spear_clocksource_init(void)
{
u32 tick_rate;
u16 val;
which controls AHB bus master arbitration and some
performance parameters(priority, prefech size).
-config TEGRA_EMC_SCALING_ENABLE
- bool "Enable scaling the memory frequency"
-
endmenu
static int dcscb_power_up(unsigned int cpu, unsigned int cluster)
{
unsigned int rst_hold, cpumask = (1 << cpu);
- unsigned int all_mask = dcscb_allcpus_mask[cluster];
+ unsigned int all_mask;
pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
if (cpu >= 4 || cluster >= 2)
return -EINVAL;
+ all_mask = dcscb_allcpus_mask[cluster];
+
/*
* Since this is called with IRQs enabled, and no arch_spin_lock_irq
* variant exists, we need to disable IRQs manually here.
cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
cpumask = (1 << cpu);
- all_mask = dcscb_allcpus_mask[cluster];
pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
BUG_ON(cpu >= 4 || cluster >= 2);
+ all_mask = dcscb_allcpus_mask[cluster];
+
__mcpm_cpu_going_down(cpu, cluster);
arch_spin_lock(&dcscb_lock);
* +--------------------------+
* | 31 20 | 19 0 |
* +--------------------------+
- * | u_volt | freq(kHz) |
+ * | m_volt | freq(kHz) |
* +--------------------------+
*/
#define MULT_FACTOR 20
ret = ve_spc_read_sys_cfg(SYSCFG_SCC, off, &data);
if (!ret) {
opps->freq = (data & FREQ_MASK) * MULT_FACTOR;
- opps->u_volt = data >> VOLT_SHIFT;
+ opps->u_volt = (data >> VOLT_SHIFT) * 1000;
} else {
break;
}
bool
select CPU_USE_DOMAINS if MMU
select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
- select TLS_REG_EMUL if SMP || !MMU
select NEED_KUSER_HELPERS
+ select TLS_REG_EMUL if SMP || !MMU
config CPU_32v4
bool
select CPU_USE_DOMAINS if MMU
select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
- select TLS_REG_EMUL if SMP || !MMU
select NEED_KUSER_HELPERS
+ select TLS_REG_EMUL if SMP || !MMU
config CPU_32v4T
bool
select CPU_USE_DOMAINS if MMU
select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
- select TLS_REG_EMUL if SMP || !MMU
select NEED_KUSER_HELPERS
+ select TLS_REG_EMUL if SMP || !MMU
config CPU_32v5
bool
select CPU_USE_DOMAINS if MMU
select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
- select TLS_REG_EMUL if SMP || !MMU
select NEED_KUSER_HELPERS
+ select TLS_REG_EMUL if SMP || !MMU
config CPU_32v6
bool
mapping->nr_bitmaps = 1;
mapping->extensions = extensions;
mapping->base = base;
- mapping->size = bitmap_size << PAGE_SHIFT;
mapping->bits = BITS_PER_BYTE * bitmap_size;
+ mapping->size = mapping->bits << PAGE_SHIFT;
spin_lock_init(&mapping->lock);
vdp.sign = vfp_sign_negate(vdp.sign);
vfp_double_unpack(&vdn, vfp_get_double(dd));
+ if (vdn.exponent == 0 && vdn.significand)
+ vfp_double_normalise_denormal(&vdn);
if (negate & NEG_SUBTRACT)
vdn.sign = vfp_sign_negate(vdn.sign);
v = vfp_get_float(sd);
pr_debug("VFP: s%u = %08x\n", sd, v);
vfp_single_unpack(&vsn, v);
+ if (vsn.exponent == 0 && vsn.significand)
+ vfp_single_normalise_denormal(&vsn);
if (negate & NEG_SUBTRACT)
vsn.sign = vfp_sign_negate(vsn.sign);
source "drivers/cpuidle/Kconfig"
-source "kernel/power/Kconfig"
-
source "drivers/cpufreq/Kconfig"
endmenu
void *vdso;
} mm_context_t;
+#define INIT_MM_CONTEXT(name) \
+ .context.id_lock = __RAW_SPIN_LOCK_UNLOCKED(name.context.id_lock),
+
#define ASID(mm) ((mm)->context.id & 0xffff)
extern void paging_init(void);
#ifndef __ASM_TLB_H
#define __ASM_TLB_H
+#define __tlb_remove_pmd_tlb_entry __tlb_remove_pmd_tlb_entry
#include <asm-generic/tlb.h>
}
#endif
+static inline void __tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp,
+ unsigned long address)
+{
+ tlb_add_flush(tlb, address);
+}
#endif
__SYSCALL(379, sys_finit_module)
__SYSCALL(380, sys_sched_setattr)
__SYSCALL(381, sys_sched_getattr)
+__SYSCALL(382, sys_renameat2)
-#define __NR_compat_syscalls 379
+#define __NR_compat_syscalls 383
/*
* Compat syscall numbers used by the AArch64 kernel.
if (call_break_hook(regs, esr) == DBG_HOOK_HANDLED)
return 0;
- pr_warn("unexpected brk exception at %lx, esr=0x%x\n",
- (long)instruction_pointer(regs), esr);
-
if (!user_mode(regs))
return -EFAULT;
static int __init arm64_device_init(void)
{
- of_clk_init(NULL);
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
return 0;
}
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/clocksource.h>
+#include <linux/clk-provider.h>
#include <clocksource/arm_arch_timer.h>
{
u32 arch_timer_rate;
+ of_clk_init(NULL);
clocksource_of_init();
arch_timer_rate = arch_timer_get_rate();
#define RR_RID_MASK 0x00000000ffffff00L
#define RR_TO_RID(val) ((val >> 8) & 0xffffff)
-/*
- * Flush the TLB for address range START to END and, if not in fast mode, release the
- * freed pages that where gathered up to this point.
- */
static inline void
-ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
+ia64_tlb_flush_mmu_tlbonly(struct mmu_gather *tlb, unsigned long start, unsigned long end)
{
- unsigned long i;
- unsigned int nr;
-
- if (!tlb->need_flush)
- return;
tlb->need_flush = 0;
if (tlb->fullmm) {
flush_tlb_range(&vma, ia64_thash(start), ia64_thash(end));
}
+}
+
+static inline void
+ia64_tlb_flush_mmu_free(struct mmu_gather *tlb)
+{
+ unsigned long i;
+ unsigned int nr;
+
/* lastly, release the freed pages */
nr = tlb->nr;
free_page_and_swap_cache(tlb->pages[i]);
}
+/*
+ * Flush the TLB for address range START to END and, if not in fast mode, release the
+ * freed pages that where gathered up to this point.
+ */
+static inline void
+ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
+{
+ if (!tlb->need_flush)
+ return;
+ ia64_tlb_flush_mmu_tlbonly(tlb, start, end);
+ ia64_tlb_flush_mmu_free(tlb);
+}
+
static inline void __tlb_alloc_page(struct mmu_gather *tlb)
{
unsigned long addr = __get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0);
return tlb->max - tlb->nr;
}
+static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
+{
+ ia64_tlb_flush_mmu_tlbonly(tlb, tlb->start_addr, tlb->end_addr);
+}
+
+static inline void tlb_flush_mmu_free(struct mmu_gather *tlb)
+{
+ ia64_tlb_flush_mmu_free(tlb);
+}
+
static inline void tlb_flush_mmu(struct mmu_gather *tlb)
{
ia64_tlb_flush_mmu(tlb, tlb->start_addr, tlb->end_addr);
* Switch into virtual mode:
*/
movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \
- |IA64_PSR_DI|IA64_PSR_AC)
+ |IA64_PSR_DI)
;;
mov cr.ipsr=r16
movl r17=1f
#include <asm/unistd.h>
#include <asm/errno.h>
-#if 1
+#if 0
# define PSR_DEFAULT_BITS psr.ac
#else
# define PSR_DEFAULT_BITS 0
#include "kvm_minstate.h"
#include "vti.h"
-#if 1
+#if 0
# define PSR_DEFAULT_BITS psr.ac
#else
# define PSR_DEFAULT_BITS 0
cpumask_clear(&new_affinity);
cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity);
}
- __irq_set_affinity_locked(data, &new_affinity);
+ irq_set_affinity_locked(data, &new_affinity, false);
}
static int octeon_irq_ciu_set_affinity(struct irq_data *data,
void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
unsigned long pfn);
void (*flush_icache_range)(unsigned long start, unsigned long end);
+EXPORT_SYMBOL_GPL(flush_icache_range);
void (*local_flush_icache_range)(unsigned long start, unsigned long end);
void (*__flush_cache_vmap)(void);
void (*__flush_cache_vunmap)(void);
void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
-void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
-
EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range);
+void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
/* MIPS specific cache operations */
void (*flush_cache_sigtramp)(unsigned long addr);
#ifndef _ASMPARISC_SHMPARAM_H
#define _ASMPARISC_SHMPARAM_H
-#define __ARCH_FORCE_SHMLBA 1
-
-#define SHMLBA 0x00400000 /* attach addr needs to be 4 Mb aligned */
+#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
+#define SHM_COLOUR 0x00400000 /* shared mappings colouring */
#endif /* _ASMPARISC_SHMPARAM_H */
* specifically accesses it, of course) */
flush_tlb_page(mpnt, addr);
- if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
+ if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1))
+ != (addr & (SHM_COLOUR - 1))) {
__flush_cache_page(mpnt, addr, page_to_phys(page));
if (old_addr)
printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? (char *)mpnt->vm_file->f_path.dentry->d_name.name : "(null)");
static int get_offset(unsigned int last_mmap)
{
- return (last_mmap & (SHMLBA-1)) >> PAGE_SHIFT;
+ return (last_mmap & (SHM_COLOUR-1)) >> PAGE_SHIFT;
}
static unsigned long shared_align_offset(unsigned int last_mmap,
static inline unsigned long COLOR_ALIGN(unsigned long addr,
unsigned int last_mmap, unsigned long pgoff)
{
- unsigned long base = (addr+SHMLBA-1) & ~(SHMLBA-1);
- unsigned long off = (SHMLBA-1) &
+ unsigned long base = (addr+SHM_COLOUR-1) & ~(SHM_COLOUR-1);
+ unsigned long off = (SHM_COLOUR-1) &
(shared_align_offset(last_mmap, pgoff) << PAGE_SHIFT);
return base + off;
if (flags & MAP_FIXED) {
if ((flags & MAP_SHARED) && last_mmap &&
(addr - shared_align_offset(last_mmap, pgoff))
- & (SHMLBA - 1))
+ & (SHM_COLOUR - 1))
return -EINVAL;
goto found_addr;
}
info.length = len;
info.low_limit = mm->mmap_legacy_base;
info.high_limit = mmap_upper_limit();
- info.align_mask = last_mmap ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
info.align_offset = shared_align_offset(last_mmap, pgoff);
addr = vm_unmapped_area(&info);
if (flags & MAP_FIXED) {
if ((flags & MAP_SHARED) && last_mmap &&
(addr - shared_align_offset(last_mmap, pgoff))
- & (SHMLBA - 1))
+ & (SHM_COLOUR - 1))
return -EINVAL;
goto found_addr;
}
info.length = len;
info.low_limit = PAGE_SIZE;
info.high_limit = mm->mmap_base;
- info.align_mask = last_mmap ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
info.align_offset = shared_align_offset(last_mmap, pgoff);
addr = vm_unmapped_area(&info);
if (!(addr & ~PAGE_MASK))
ENTRY_COMP(vmsplice)
ENTRY_COMP(move_pages) /* 295 */
ENTRY_SAME(getcpu)
- ENTRY_SAME(epoll_pwait)
+ ENTRY_COMP(epoll_pwait)
ENTRY_COMP(statfs64)
ENTRY_COMP(fstatfs64)
ENTRY_COMP(kexec_load) /* 300 */
return 0;
/* if a load or store fault occured we can get the faulty addr */
- d = &__get_cpu_var(exception_data);
+ d = this_cpu_ptr(&exception_data);
fault_addr = d->fault_addr;
/* error in load or store? */
fix = search_exception_tables(regs->iaoq[0]);
if (fix) {
struct exception_data *d;
- d = &__get_cpu_var(exception_data);
+ d = this_cpu_ptr(&exception_data);
d->fault_ip = regs->iaoq[0];
d->fault_space = regs->isr;
d->fault_addr = regs->ior;
unsigned long in_devfn)
{
struct pci_controller* hose;
- struct pci_bus *bus = NULL;
+ struct pci_bus *tmp_bus, *bus = NULL;
struct device_node *hose_node;
/* Argh ! Please forgive me for that hack, but that's the
* used on pre-domains setup. We return the first match
*/
- list_for_each_entry(bus, &pci_root_buses, node) {
- if (in_bus >= bus->number && in_bus <= bus->busn_res.end)
+ list_for_each_entry(tmp_bus, &pci_root_buses, node) {
+ if (in_bus >= tmp_bus->number &&
+ in_bus <= tmp_bus->busn_res.end) {
+ bus = tmp_bus;
break;
- bus = NULL;
+ }
}
if (bus == NULL || bus->dev.of_node == NULL)
return -ENODEV;
return distance;
}
+EXPORT_SYMBOL(__node_distance);
static void initialize_distance_lookup_table(int nid,
const __be32 *associativity)
/* public: */
unsigned int count;
struct device dev;
- struct ccw_device *cdev[0];
struct work_struct ungroup_work;
+ struct ccw_device *cdev[0];
};
/**
#define SIGP_STATUS_INCORRECT_STATE 0x00000200UL
#define SIGP_STATUS_NOT_RUNNING 0x00000400UL
+#ifndef __ASSEMBLY__
+
+static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status)
+{
+ register unsigned int reg1 asm ("1") = parm;
+ int cc;
+
+ asm volatile(
+ " sigp %1,%2,0(%3)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ : "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc");
+ if (status && cc == 1)
+ *status = reg1;
+ return cc;
+}
+
+#endif /* __ASSEMBLY__ */
+
#endif /* __S390_ASM_SIGP_H */
#ifndef __ASM_SMP_H
#define __ASM_SMP_H
+#include <asm/sigp.h>
+
#ifdef CONFIG_SMP
#include <asm/lowcore.h>
static inline int smp_vcpu_scheduled(int cpu) { return 1; }
static inline void smp_yield_cpu(int cpu) { }
static inline void smp_yield(void) { }
-static inline void smp_stop_cpu(void) { }
static inline void smp_fill_possible_mask(void) { }
+static inline void smp_stop_cpu(void)
+{
+ u16 pcpu = stap();
+
+ for (;;) {
+ __pcpu_sigp(pcpu, SIGP_STOP, 0, NULL);
+ cpu_relax();
+ }
+}
+
#endif /* CONFIG_SMP */
#ifdef CONFIG_HOTPLUG_CPU
tlb->batch = NULL;
}
-static inline void tlb_flush_mmu(struct mmu_gather *tlb)
+static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
{
__tlb_flush_mm_lazy(tlb->mm);
+}
+
+static inline void tlb_flush_mmu_free(struct mmu_gather *tlb)
+{
tlb_table_flush(tlb);
}
+
+static inline void tlb_flush_mmu(struct mmu_gather *tlb)
+{
+ tlb_flush_mmu_tlbonly(tlb);
+ tlb_flush_mmu_free(tlb);
+}
+
static inline void tlb_finish_mmu(struct mmu_gather *tlb,
unsigned long start, unsigned long end)
{
#define __NR_finit_module 344
#define __NR_sched_setattr 345
#define __NR_sched_getattr 346
-#define NR_syscalls 345
+#define __NR_renameat2 347
+#define NR_syscalls 348
/*
* There are some system calls that are not present on 64 bit, some
/*
- * Compat sytem call wrappers.
+ * Compat system call wrappers.
*
* Copyright IBM Corp. 2014
*/
COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags);
COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags);
COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags);
+COMPAT_SYSCALL_WRAP5(renameat2, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, unsigned int, flags);
char *mode;
mode = user_mode(regs) ? "User" : "Krnl";
- printk("%s PSW : %p %p (%pSR)\n",
- mode, (void *) regs->psw.mask,
- (void *) regs->psw.addr,
- (void *) regs->psw.addr);
+ printk("%s PSW : %p %p", mode, (void *)regs->psw.mask, (void *)regs->psw.addr);
+ if (!user_mode(regs))
+ printk(" (%pSR)", (void *)regs->psw.addr);
+ printk("\n");
printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x "
"P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER),
mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO),
if (task->thread.per_flags & PER_FLAG_NO_TE)
cr_new &= ~(1UL << 55);
if (cr_new != cr)
- __ctl_load(cr, 0, 0);
+ __ctl_load(cr_new, 0, 0);
/* Set or clear transaction execution TDC bits 62 and 63. */
__ctl_store(cr, 2, 2);
cr_new = cr & ~3UL;
/* Setup zfcpdump support */
setup_zfcpdump();
}
+
+#ifdef CONFIG_32BIT
+static int no_removal_warning __initdata;
+
+static int __init parse_no_removal_warning(char *str)
+{
+ no_removal_warning = 1;
+ return 0;
+}
+__setup("no_removal_warning", parse_no_removal_warning);
+
+static int __init removal_warning(void)
+{
+ if (no_removal_warning)
+ return 0;
+ printk(KERN_ALERT "\n\n");
+ printk(KERN_CONT "Warning - you are using a 31 bit kernel!\n\n");
+ printk(KERN_CONT "We plan to remove 31 bit kernel support from the kernel sources in March 2015.\n");
+ printk(KERN_CONT "Currently we assume that nobody is using the 31 bit kernel on old 31 bit\n");
+ printk(KERN_CONT "hardware anymore. If you think that the code should not be removed and also\n");
+ printk(KERN_CONT "future versions of the Linux kernel should be able to run in 31 bit mode\n");
+ printk(KERN_CONT "please let us know. Please write to:\n");
+ printk(KERN_CONT "linux390@de.ibm.com (mail address) and/or\n");
+ printk(KERN_CONT "linux-s390@vger.kernel.org (mailing list).\n\n");
+ printk(KERN_CONT "Thank you!\n\n");
+ printk(KERN_CONT "If this kernel runs on a 64 bit machine you may consider using a 64 bit kernel.\n");
+ printk(KERN_CONT "This message can be disabled with the \"no_removal_warning\" kernel parameter.\n");
+ schedule_timeout_uninterruptible(300 * HZ);
+ return 0;
+}
+early_initcall(removal_warning);
+#endif
/*
* Signal processor helper functions.
*/
-static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status)
-{
- register unsigned int reg1 asm ("1") = parm;
- int cc;
-
- asm volatile(
- " sigp %1,%2,0(%3)\n"
- " ipm %0\n"
- " srl %0,28\n"
- : "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc");
- if (status && cc == 1)
- *status = reg1;
- return cc;
-}
-
static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status)
{
int cc;
SYSCALL(sys_finit_module,sys_finit_module,compat_sys_finit_module)
SYSCALL(sys_sched_setattr,sys_sched_setattr,compat_sys_sched_setattr) /* 345 */
SYSCALL(sys_sched_getattr,sys_sched_getattr,compat_sys_sched_getattr)
+SYSCALL(sys_renameat2,sys_renameat2,compat_sys_renameat2)
register unsigned long reg0 asm("0") = 0;
unsigned long tmp1, tmp2;
- if (unlikely(!size))
- return 0;
- update_primary_asce(current);
asm volatile(
" la %2,0(%1)\n"
" la %3,0(%0,%1)\n"
unsigned long __strnlen_user(const char __user *src, unsigned long size)
{
+ if (unlikely(!size))
+ return 0;
update_primary_asce(current);
return strnlen_user_srst(src, size);
}
return 0;
}
+static int bad_address(void *p)
+{
+ unsigned long dummy;
+
+ return probe_kernel_address((unsigned long *)p, dummy);
+}
+
+#ifdef CONFIG_64BIT
+static void dump_pagetable(unsigned long asce, unsigned long address)
+{
+ unsigned long *table = __va(asce & PAGE_MASK);
+
+ pr_alert("AS:%016lx ", asce);
+ switch (asce & _ASCE_TYPE_MASK) {
+ case _ASCE_TYPE_REGION1:
+ table = table + ((address >> 53) & 0x7ff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont("R1:%016lx ", *table);
+ if (*table & _REGION_ENTRY_INVALID)
+ goto out;
+ table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+ /* fallthrough */
+ case _ASCE_TYPE_REGION2:
+ table = table + ((address >> 42) & 0x7ff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont("R2:%016lx ", *table);
+ if (*table & _REGION_ENTRY_INVALID)
+ goto out;
+ table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+ /* fallthrough */
+ case _ASCE_TYPE_REGION3:
+ table = table + ((address >> 31) & 0x7ff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont("R3:%016lx ", *table);
+ if (*table & (_REGION_ENTRY_INVALID | _REGION3_ENTRY_LARGE))
+ goto out;
+ table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+ /* fallthrough */
+ case _ASCE_TYPE_SEGMENT:
+ table = table + ((address >> 20) & 0x7ff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont(KERN_CONT "S:%016lx ", *table);
+ if (*table & (_SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_LARGE))
+ goto out;
+ table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN);
+ }
+ table = table + ((address >> 12) & 0xff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont("P:%016lx ", *table);
+out:
+ pr_cont("\n");
+ return;
+bad:
+ pr_cont("BAD\n");
+}
+
+#else /* CONFIG_64BIT */
+
+static void dump_pagetable(unsigned long asce, unsigned long address)
+{
+ unsigned long *table = __va(asce & PAGE_MASK);
+
+ pr_alert("AS:%08lx ", asce);
+ table = table + ((address >> 20) & 0x7ff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont("S:%08lx ", *table);
+ if (*table & _SEGMENT_ENTRY_INVALID)
+ goto out;
+ table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN);
+ table = table + ((address >> 12) & 0xff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont("P:%08lx ", *table);
+out:
+ pr_cont("\n");
+ return;
+bad:
+ pr_cont("BAD\n");
+}
+
+#endif /* CONFIG_64BIT */
+
+static void dump_fault_info(struct pt_regs *regs)
+{
+ unsigned long asce;
+
+ pr_alert("Fault in ");
+ switch (regs->int_parm_long & 3) {
+ case 3:
+ pr_cont("home space ");
+ break;
+ case 2:
+ pr_cont("secondary space ");
+ break;
+ case 1:
+ pr_cont("access register ");
+ break;
+ case 0:
+ pr_cont("primary space ");
+ break;
+ }
+ pr_cont("mode while using ");
+ if (!user_space_fault(regs)) {
+ asce = S390_lowcore.kernel_asce;
+ pr_cont("kernel ");
+ }
+#ifdef CONFIG_PGSTE
+ else if ((current->flags & PF_VCPU) && S390_lowcore.gmap) {
+ struct gmap *gmap = (struct gmap *)S390_lowcore.gmap;
+ asce = gmap->asce;
+ pr_cont("gmap ");
+ }
+#endif
+ else {
+ asce = S390_lowcore.user_asce;
+ pr_cont("user ");
+ }
+ pr_cont("ASCE.\n");
+ dump_pagetable(asce, regs->int_parm_long & __FAIL_ADDR_MASK);
+}
+
static inline void report_user_fault(struct pt_regs *regs, long signr)
{
if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
regs->int_code);
print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN);
printk(KERN_CONT "\n");
- printk(KERN_ALERT "failing address: %lX\n",
- regs->int_parm_long & __FAIL_ADDR_MASK);
+ printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n",
+ regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
+ dump_fault_info(regs);
show_regs(regs);
}
address = regs->int_parm_long & __FAIL_ADDR_MASK;
if (!user_space_fault(regs))
printk(KERN_ALERT "Unable to handle kernel pointer dereference"
- " at virtual kernel address %p\n", (void *)address);
+ " in virtual kernel address space\n");
else
printk(KERN_ALERT "Unable to handle kernel paging request"
- " at virtual user address %p\n", (void *)address);
-
+ " in virtual user address space\n");
+ printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n",
+ regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
+ dump_fault_info(regs);
die(regs, "Oops");
do_exit(SIGKILL);
}
}
}
+static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
+{
+}
+
+static inline void tlb_flush_mmu_free(struct mmu_gather *tlb)
+{
+}
+
static inline void tlb_flush_mmu(struct mmu_gather *tlb)
{
}
extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
unsigned long end);
+static inline void
+tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
+{
+ flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end);
+}
+
+static inline void
+tlb_flush_mmu_free(struct mmu_gather *tlb)
+{
+ init_tlb_gather(tlb);
+}
+
static inline void
tlb_flush_mmu(struct mmu_gather *tlb)
{
if (!tlb->need_flush)
return;
- flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end);
- init_tlb_gather(tlb);
+ tlb_flush_mmu_tlbonly(tlb);
+ tlb_flush_mmu_free(tlb);
}
/* tlb_finish_mmu
extern int os_get_ifname(int fd, char *namebuf);
extern int os_set_slip(int fd);
extern int os_mode_fd(int fd, int mode);
+extern int os_fsync_file(int fd);
extern int os_seek_file(int fd, unsigned long long offset);
extern int os_open_file(const char *file, struct openflags flags, int mode);
*/
os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE);
+ os_fsync_file(physmem_fd);
bootmap_size = init_bootmem(pfn, pfn + delta);
free_bootmem(__pa(reserve_end) + bootmap_size,
{
close(fd);
}
+int os_fsync_file(int fd)
+{
+ if (fsync(fd) < 0)
+ return -errno;
+ return 0;
+}
int os_seek_file(int fd, unsigned long long offset)
{
#endif
do_uml_initcalls();
+ change_sig(SIGPIPE, 0);
ret = linux_main(argc, argv);
/*
#include <string.h>
#include <sys/stat.h>
#include <sys/mman.h>
-#include <sys/param.h>
+#include <sys/vfs.h>
+#include <linux/magic.h>
#include <init.h>
#include <os.h>
-/* Modified by which_tmpdir, which is called during early boot */
-static char *default_tmpdir = "/tmp";
-
-/*
- * Modified when creating the physical memory file and when checking
- * the tmp filesystem for usability, both happening during early boot.
- */
+/* Set by make_tempfile() during early boot. */
static char *tempdir = NULL;
-static void __init find_tempdir(void)
+/* Check if dir is on tmpfs. Return 0 if yes, -1 if no or error. */
+static int __init check_tmpfs(const char *dir)
{
- const char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
- int i;
- char *dir = NULL;
-
- if (tempdir != NULL)
- /* We've already been called */
- return;
- for (i = 0; dirs[i]; i++) {
- dir = getenv(dirs[i]);
- if ((dir != NULL) && (*dir != '\0'))
- break;
- }
- if ((dir == NULL) || (*dir == '\0'))
- dir = default_tmpdir;
+ struct statfs st;
- tempdir = malloc(strlen(dir) + 2);
- if (tempdir == NULL) {
- fprintf(stderr, "Failed to malloc tempdir, "
- "errno = %d\n", errno);
- return;
- }
- strcpy(tempdir, dir);
- strcat(tempdir, "/");
-}
-
-/*
- * Remove bytes from the front of the buffer and refill it so that if there's a
- * partial string that we care about, it will be completed, and we can recognize
- * it.
- */
-static int pop(int fd, char *buf, size_t size, size_t npop)
-{
- ssize_t n;
- size_t len = strlen(&buf[npop]);
-
- memmove(buf, &buf[npop], len + 1);
- n = read(fd, &buf[len], size - len - 1);
- if (n < 0)
- return -errno;
-
- buf[len + n] = '\0';
- return 1;
-}
-
-/*
- * This will return 1, with the first character in buf being the
- * character following the next instance of c in the file. This will
- * read the file as needed. If there's an error, -errno is returned;
- * if the end of the file is reached, 0 is returned.
- */
-static int next(int fd, char *buf, size_t size, char c)
-{
- ssize_t n;
- char *ptr;
-
- while ((ptr = strchr(buf, c)) == NULL) {
- n = read(fd, buf, size - 1);
- if (n == 0)
- return 0;
- else if (n < 0)
- return -errno;
-
- buf[n] = '\0';
+ printf("Checking if %s is on tmpfs...", dir);
+ if (statfs(dir, &st) < 0) {
+ printf("%s\n", strerror(errno));
+ } else if (st.f_type != TMPFS_MAGIC) {
+ printf("no\n");
+ } else {
+ printf("OK\n");
+ return 0;
}
-
- return pop(fd, buf, size, ptr - buf + 1);
+ return -1;
}
/*
- * Decode an octal-escaped and space-terminated path of the form used by
- * /proc/mounts. May be used to decode a path in-place. "out" must be at least
- * as large as the input. The output is always null-terminated. "len" gets the
- * length of the output, excluding the trailing null. Returns 0 if a full path
- * was successfully decoded, otherwise an error.
+ * Choose the tempdir to use. We want something on tmpfs so that our memory is
+ * not subject to the host's vm.dirty_ratio. If a tempdir is specified in the
+ * environment, we use that even if it's not on tmpfs, but we warn the user.
+ * Otherwise, we try common tmpfs locations, and if no tmpfs directory is found
+ * then we fall back to /tmp.
*/
-static int decode_path(const char *in, char *out, size_t *len)
+static char * __init choose_tempdir(void)
{
- char *first = out;
- int c;
+ static const char * const vars[] = {
+ "TMPDIR",
+ "TMP",
+ "TEMP",
+ NULL
+ };
+ static const char fallback_dir[] = "/tmp";
+ static const char * const tmpfs_dirs[] = {
+ "/dev/shm",
+ fallback_dir,
+ NULL
+ };
int i;
- int ret = -EINVAL;
- while (1) {
- switch (*in) {
- case '\0':
- goto out;
-
- case ' ':
- ret = 0;
- goto out;
-
- case '\\':
- in++;
- c = 0;
- for (i = 0; i < 3; i++) {
- if (*in < '0' || *in > '7')
- goto out;
- c = (c << 3) | (*in++ - '0');
- }
- *(unsigned char *)out++ = (unsigned char) c;
- break;
-
- default:
- *out++ = *in++;
- break;
+ const char *dir;
+
+ printf("Checking environment variables for a tempdir...");
+ for (i = 0; vars[i]; i++) {
+ dir = getenv(vars[i]);
+ if ((dir != NULL) && (*dir != '\0')) {
+ printf("%s\n", dir);
+ if (check_tmpfs(dir) >= 0)
+ goto done;
+ else
+ goto warn;
}
}
+ printf("none found\n");
-out:
- *out = '\0';
- *len = out - first;
- return ret;
-}
-
-/*
- * Computes the length of s when encoded with three-digit octal escape sequences
- * for the characters in chars.
- */
-static size_t octal_encoded_length(const char *s, const char *chars)
-{
- size_t len = strlen(s);
- while ((s = strpbrk(s, chars)) != NULL) {
- len += 3;
- s++;
- }
-
- return len;
-}
-
-enum {
- OUTCOME_NOTHING_MOUNTED,
- OUTCOME_TMPFS_MOUNT,
- OUTCOME_NON_TMPFS_MOUNT,
-};
-
-/* Read a line of /proc/mounts data looking for a tmpfs mount at "path". */
-static int read_mount(int fd, char *buf, size_t bufsize, const char *path,
- int *outcome)
-{
- int found;
- int match;
- char *space;
- size_t len;
-
- enum {
- MATCH_NONE,
- MATCH_EXACT,
- MATCH_PARENT,
- };
-
- found = next(fd, buf, bufsize, ' ');
- if (found != 1)
- return found;
-
- /*
- * If there's no following space in the buffer, then this path is
- * truncated, so it can't be the one we're looking for.
- */
- space = strchr(buf, ' ');
- if (space) {
- match = MATCH_NONE;
- if (!decode_path(buf, buf, &len)) {
- if (!strcmp(buf, path))
- match = MATCH_EXACT;
- else if (!strncmp(buf, path, len)
- && (path[len] == '/' || !strcmp(buf, "/")))
- match = MATCH_PARENT;
- }
-
- found = pop(fd, buf, bufsize, space - buf + 1);
- if (found != 1)
- return found;
-
- switch (match) {
- case MATCH_EXACT:
- if (!strncmp(buf, "tmpfs", strlen("tmpfs")))
- *outcome = OUTCOME_TMPFS_MOUNT;
- else
- *outcome = OUTCOME_NON_TMPFS_MOUNT;
- break;
-
- case MATCH_PARENT:
- /* This mount obscures any previous ones. */
- *outcome = OUTCOME_NOTHING_MOUNTED;
- break;
- }
+ for (i = 0; tmpfs_dirs[i]; i++) {
+ dir = tmpfs_dirs[i];
+ if (check_tmpfs(dir) >= 0)
+ goto done;
}
- return next(fd, buf, bufsize, '\n');
+ dir = fallback_dir;
+warn:
+ printf("Warning: tempdir %s is not on tmpfs\n", dir);
+done:
+ /* Make a copy since getenv results may not remain valid forever. */
+ return strdup(dir);
}
-/* which_tmpdir is called only during early boot */
-static int checked_tmpdir = 0;
-
/*
- * Look for a tmpfs mounted at /dev/shm. I couldn't find a cleaner
- * way to do this than to parse /proc/mounts. statfs will return the
- * same filesystem magic number and fs id for both /dev and /dev/shm
- * when they are both tmpfs, so you can't tell if they are different
- * filesystems. Also, there seems to be no other way of finding the
- * mount point of a filesystem from within it.
- *
- * If a /dev/shm tmpfs entry is found, then we switch to using it.
- * Otherwise, we stay with the default /tmp.
+ * Create an unlinked tempfile in a suitable tempdir. template must be the
+ * basename part of the template with a leading '/'.
*/
-static void which_tmpdir(void)
+static int __init make_tempfile(const char *template)
{
+ char *tempname;
int fd;
- int found;
- int outcome;
- char *path;
- char *buf;
- size_t bufsize;
- if (checked_tmpdir)
- return;
-
- checked_tmpdir = 1;
-
- printf("Checking for tmpfs mount on /dev/shm...");
-
- path = realpath("/dev/shm", NULL);
- if (!path) {
- printf("failed to check real path, errno = %d\n", errno);
- return;
- }
- printf("%s...", path);
-
- /*
- * The buffer needs to be able to fit the full octal-escaped path, a
- * space, and a trailing null in order to successfully decode it.
- */
- bufsize = octal_encoded_length(path, " \t\n\\") + 2;
-
- if (bufsize < 128)
- bufsize = 128;
-
- buf = malloc(bufsize);
- if (!buf) {
- printf("malloc failed, errno = %d\n", errno);
- goto out;
- }
- buf[0] = '\0';
-
- fd = open("/proc/mounts", O_RDONLY);
- if (fd < 0) {
- printf("failed to open /proc/mounts, errno = %d\n", errno);
- goto out1;
- }
-
- outcome = OUTCOME_NOTHING_MOUNTED;
- while (1) {
- found = read_mount(fd, buf, bufsize, path, &outcome);
- if (found != 1)
- break;
- }
-
- if (found < 0) {
- printf("read returned errno %d\n", -found);
- } else {
- switch (outcome) {
- case OUTCOME_TMPFS_MOUNT:
- printf("OK\n");
- default_tmpdir = "/dev/shm";
- break;
-
- case OUTCOME_NON_TMPFS_MOUNT:
- printf("not tmpfs\n");
- break;
-
- default:
- printf("nothing mounted on /dev/shm\n");
- break;
+ if (tempdir == NULL) {
+ tempdir = choose_tempdir();
+ if (tempdir == NULL) {
+ fprintf(stderr, "Failed to choose tempdir: %s\n",
+ strerror(errno));
+ return -1;
}
}
- close(fd);
-out1:
- free(buf);
-out:
- free(path);
-}
-
-static int __init make_tempfile(const char *template, char **out_tempname,
- int do_unlink)
-{
- char *tempname;
- int fd;
-
- which_tmpdir();
- tempname = malloc(MAXPATHLEN);
+ tempname = malloc(strlen(tempdir) + strlen(template) + 1);
if (tempname == NULL)
return -1;
- find_tempdir();
- if ((tempdir == NULL) || (strlen(tempdir) >= MAXPATHLEN))
- goto out;
-
- if (template[0] != '/')
- strcpy(tempname, tempdir);
- else
- tempname[0] = '\0';
- strncat(tempname, template, MAXPATHLEN-1-strlen(tempname));
+ strcpy(tempname, tempdir);
+ strcat(tempname, template);
fd = mkstemp(tempname);
if (fd < 0) {
fprintf(stderr, "open - cannot create %s: %s\n", tempname,
strerror(errno));
goto out;
}
- if (do_unlink && (unlink(tempname) < 0)) {
+ if (unlink(tempname) < 0) {
perror("unlink");
goto close;
}
- if (out_tempname) {
- *out_tempname = tempname;
- } else
- free(tempname);
+ free(tempname);
return fd;
close:
close(fd);
return -1;
}
-#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
+#define TEMPNAME_TEMPLATE "/vm_file-XXXXXX"
static int __init create_tmp_file(unsigned long long len)
{
int fd, err;
char zero;
- fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
+ fd = make_tempfile(TEMPNAME_TEMPLATE);
if (fd < 0)
exit(1);
return fd;
}
-
void __init check_tmpexec(void)
{
void *addr;
addr = mmap(NULL, UM_KERN_PAGE_SIZE,
PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
- printf("Checking PROT_EXEC mmap in %s...",tempdir);
- fflush(stdout);
+ printf("Checking PROT_EXEC mmap in %s...", tempdir);
if (addr == MAP_FAILED) {
err = errno;
- perror("failed");
+ printf("%s\n", strerror(err));
close(fd);
if (err == EPERM)
- printf("%s must be not mounted noexec\n",tempdir);
+ printf("%s must be not mounted noexec\n", tempdir);
exit(1);
}
printf("OK\n");
PHONY += kvmconfig
kvmconfig:
$(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target))
- $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config arch/x86/configs/kvm_guest.config
- $(Q)yes "" | $(MAKE) oldconfig
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(srctree)/arch/x86/configs/kvm_guest.config
+ $(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig
define archhelp
echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
| X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \
| X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \
| X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \
- | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE))
+ | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE | X86_CR4_SMAP))
#define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)
{
struct mce m;
int i;
- unsigned long *v;
this_cpu_inc(mce_poll_count);
if (!(m.status & MCI_STATUS_VAL))
continue;
- v = &get_cpu_var(mce_polled_error);
- set_bit(0, v);
+ this_cpu_write(mce_polled_error, 1);
/*
* Uncorrected or signalled events are handled by the exception
* handler when it is enabled, so don't process those here.
* cmci_discover_lock protects against parallel discovery attempts
* which could race against each other.
*/
-static DEFINE_RAW_SPINLOCK(cmci_discover_lock);
+static DEFINE_SPINLOCK(cmci_discover_lock);
#define CMCI_THRESHOLD 1
#define CMCI_POLL_INTERVAL (30 * HZ)
int bank;
u64 val;
- raw_spin_lock_irqsave(&cmci_discover_lock, flags);
+ spin_lock_irqsave(&cmci_discover_lock, flags);
owned = __get_cpu_var(mce_banks_owned);
for_each_set_bit(bank, owned, MAX_NR_BANKS) {
rdmsrl(MSR_IA32_MCx_CTL2(bank), val);
val &= ~MCI_CTL2_CMCI_EN;
wrmsrl(MSR_IA32_MCx_CTL2(bank), val);
}
- raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
+ spin_unlock_irqrestore(&cmci_discover_lock, flags);
}
static bool cmci_storm_detect(void)
int i;
int bios_wrong_thresh = 0;
- raw_spin_lock_irqsave(&cmci_discover_lock, flags);
+ spin_lock_irqsave(&cmci_discover_lock, flags);
for (i = 0; i < banks; i++) {
u64 val;
int bios_zero_thresh = 0;
WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks)));
}
}
- raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
+ spin_unlock_irqrestore(&cmci_discover_lock, flags);
if (mca_cfg.bios_cmci_threshold && bios_wrong_thresh) {
pr_info_once(
"bios_cmci_threshold: Some banks do not have valid thresholds set\n");
if (!cmci_supported(&banks))
return;
- raw_spin_lock_irqsave(&cmci_discover_lock, flags);
+ spin_lock_irqsave(&cmci_discover_lock, flags);
for (i = 0; i < banks; i++)
__cmci_disable_bank(i);
- raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
+ spin_unlock_irqrestore(&cmci_discover_lock, flags);
}
static void cmci_rediscover_work_func(void *arg)
if (!cmci_supported(&banks))
return;
- raw_spin_lock_irqsave(&cmci_discover_lock, flags);
+ spin_lock_irqsave(&cmci_discover_lock, flags);
__cmci_disable_bank(bank);
- raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
+ spin_unlock_irqrestore(&cmci_discover_lock, flags);
}
static void intel_init_cmci(void)
#define INTEL_RAPL_PKG 0x2 /* pseudo-encoding */
#define RAPL_IDX_RAM_NRG_STAT 2 /* DRAM */
#define INTEL_RAPL_RAM 0x3 /* pseudo-encoding */
-#define RAPL_IDX_PP1_NRG_STAT 3 /* DRAM */
+#define RAPL_IDX_PP1_NRG_STAT 3 /* gpu */
#define INTEL_RAPL_PP1 0x4 /* pseudo-encoding */
/* Clients have PP0, PKG */
1<<RAPL_IDX_PKG_NRG_STAT|\
1<<RAPL_IDX_RAM_NRG_STAT)
+/* Servers have PP0, PKG, RAM, PP1 */
+#define RAPL_IDX_HSW (1<<RAPL_IDX_PP0_NRG_STAT|\
+ 1<<RAPL_IDX_PKG_NRG_STAT|\
+ 1<<RAPL_IDX_RAM_NRG_STAT|\
+ 1<<RAPL_IDX_PP1_NRG_STAT)
+
/*
* event code: LSB 8 bits, passed in attr->config
* any other bit is reserved
NULL,
};
+static struct attribute *rapl_events_hsw_attr[] = {
+ EVENT_PTR(rapl_cores),
+ EVENT_PTR(rapl_pkg),
+ EVENT_PTR(rapl_gpu),
+ EVENT_PTR(rapl_ram),
+
+ EVENT_PTR(rapl_cores_unit),
+ EVENT_PTR(rapl_pkg_unit),
+ EVENT_PTR(rapl_gpu_unit),
+ EVENT_PTR(rapl_ram_unit),
+
+ EVENT_PTR(rapl_cores_scale),
+ EVENT_PTR(rapl_pkg_scale),
+ EVENT_PTR(rapl_gpu_scale),
+ EVENT_PTR(rapl_ram_scale),
+ NULL,
+};
+
static struct attribute_group rapl_pmu_events_group = {
.name = "events",
.attrs = NULL, /* patched at runtime */
struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
int phys_id = topology_physical_package_id(cpu);
u64 ms;
+ u64 msr_rapl_power_unit_bits;
if (pmu)
return 0;
if (phys_id < 0)
return -1;
+ if (!rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits))
+ return -1;
+
pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
if (!pmu)
return -1;
*
* we cache in local PMU instance
*/
- rdmsrl(MSR_RAPL_POWER_UNIT, pmu->hw_unit);
- pmu->hw_unit = (pmu->hw_unit >> 8) & 0x1FULL;
+ pmu->hw_unit = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
pmu->pmu = &rapl_pmu_class;
/*
switch (boot_cpu_data.x86_model) {
case 42: /* Sandy Bridge */
case 58: /* Ivy Bridge */
- case 60: /* Haswell */
- case 69: /* Haswell-Celeron */
rapl_cntr_mask = RAPL_IDX_CLN;
rapl_pmu_events_group.attrs = rapl_events_cln_attr;
break;
+ case 60: /* Haswell */
+ case 69: /* Haswell-Celeron */
+ rapl_cntr_mask = RAPL_IDX_HSW;
+ rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
+ break;
case 45: /* Sandy Bridge-EP */
case 62: /* IvyTown */
rapl_cntr_mask = RAPL_IDX_SRV;
cpu_notifier_register_begin();
for_each_online_cpu(cpu) {
- rapl_cpu_prepare(cpu);
+ ret = rapl_cpu_prepare(cpu);
+ if (ret)
+ goto out;
rapl_cpu_init(cpu);
}
hweight32(rapl_cntr_mask),
ktime_to_ms(pmu->timer_interval));
+out:
cpu_notifier_register_done();
return 0;
return base;
}
-#define KB(x) ((x) * 1024)
+#define KB(x) ((x) * 1024UL)
#define MB(x) (KB (KB (x)))
#define GB(x) (MB (KB (x)))
struct kprobe *cur = kprobe_running();
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
- switch (kcb->kprobe_status) {
- case KPROBE_HIT_SS:
- case KPROBE_REENTER:
+ if (unlikely(regs->ip == (unsigned long)cur->ainsn.insn)) {
+ /* This must happen on single-stepping */
+ WARN_ON(kcb->kprobe_status != KPROBE_HIT_SS &&
+ kcb->kprobe_status != KPROBE_REENTER);
/*
* We are here because the instruction being single
* stepped caused a page fault. We reset the current
else
reset_current_kprobe();
preempt_enable_no_resched();
- break;
- case KPROBE_HIT_ACTIVE:
- case KPROBE_HIT_SSDONE:
+ } else if (kcb->kprobe_status == KPROBE_HIT_ACTIVE ||
+ kcb->kprobe_status == KPROBE_HIT_SSDONE) {
/*
* We increment the nmissed count for accounting,
* we can also use npre/npostfault count for accounting
* fixup routine could not handle it,
* Let do_page_fault() fix it.
*/
- break;
- default:
- break;
}
+
return 0;
}
*/
static int __init set_pci_reboot(const struct dmi_system_id *d)
{
- if (reboot_type != BOOT_CF9) {
- reboot_type = BOOT_CF9;
+ if (reboot_type != BOOT_CF9_FORCE) {
+ reboot_type = BOOT_CF9_FORCE;
pr_info("%s series board detected. Selecting %s-method for reboots.\n",
d->ident, "PCI");
}
}
/*
- * Windows compatible x86 hardware expects the following on reboot:
+ * To the best of our knowledge Windows compatible x86 hardware expects
+ * the following on reboot:
*
* 1) If the FADT has the ACPI reboot register flag set, try it
* 2) If still alive, write to the keyboard controller
* 3) If still alive, write to the ACPI reboot register again
* 4) If still alive, write to the keyboard controller again
* 5) If still alive, call the EFI runtime service to reboot
- * 6) If still alive, write to the PCI IO port 0xCF9 to reboot
- * 7) If still alive, inform BIOS to do a proper reboot
+ * 6) If no EFI runtime service, call the BIOS to do a reboot
*
- * If the machine is still alive at this stage, it gives up. We default to
- * following the same pattern, except that if we're still alive after (7) we'll
- * try to force a triple fault and then cycle between hitting the keyboard
- * controller and doing that
+ * We default to following the same pattern. We also have
+ * two other reboot methods: 'triple fault' and 'PCI', which
+ * can be triggered via the reboot= kernel boot option or
+ * via quirks.
+ *
+ * This means that this function can never return, it can misbehave
+ * by not rebooting properly and hanging.
*/
static void native_machine_emergency_restart(void)
{
for (;;) {
/* Could also try the reset bit in the Hammer NB */
switch (reboot_type) {
+ case BOOT_ACPI:
+ acpi_reboot();
+ reboot_type = BOOT_KBD;
+ break;
+
case BOOT_KBD:
mach_reboot_fixups(); /* For board specific fixups */
}
break;
- case BOOT_TRIPLE:
- load_idt(&no_idt);
- __asm__ __volatile__("int3");
-
- /* We're probably dead after this, but... */
- reboot_type = BOOT_KBD;
- break;
-
- case BOOT_BIOS:
- machine_real_restart(MRR_BIOS);
-
- /* We're probably dead after this, but... */
- reboot_type = BOOT_TRIPLE;
- break;
-
- case BOOT_ACPI:
- acpi_reboot();
- reboot_type = BOOT_KBD;
- break;
-
case BOOT_EFI:
if (efi_enabled(EFI_RUNTIME_SERVICES))
efi.reset_system(reboot_mode == REBOOT_WARM ?
EFI_RESET_WARM :
EFI_RESET_COLD,
EFI_SUCCESS, 0, NULL);
- reboot_type = BOOT_CF9_COND;
+ reboot_type = BOOT_BIOS;
+ break;
+
+ case BOOT_BIOS:
+ machine_real_restart(MRR_BIOS);
+
+ /* We're probably dead after this, but... */
+ reboot_type = BOOT_CF9_SAFE;
break;
- case BOOT_CF9:
+ case BOOT_CF9_FORCE:
port_cf9_safe = true;
/* Fall through */
- case BOOT_CF9_COND:
+ case BOOT_CF9_SAFE:
if (port_cf9_safe) {
- u8 reboot_code = reboot_mode == REBOOT_WARM ?
- 0x06 : 0x0E;
+ u8 reboot_code = reboot_mode == REBOOT_WARM ? 0x06 : 0x0E;
u8 cf9 = inb(0xcf9) & ~reboot_code;
outb(cf9|2, 0xcf9); /* Request hard reset */
udelay(50);
outb(cf9|reboot_code, 0xcf9);
udelay(50);
}
- reboot_type = BOOT_BIOS;
+ reboot_type = BOOT_TRIPLE;
+ break;
+
+ case BOOT_TRIPLE:
+ load_idt(&no_idt);
+ __asm__ __volatile__("int3");
+
+ /* We're probably dead after this, but... */
+ reboot_type = BOOT_KBD;
break;
}
}
const u32 kvm_supported_word9_x86_features =
F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) |
F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) |
- F(ADX);
+ F(ADX) | F(SMAP);
/* all calls to cpuid_count() should be made on the same cpu */
get_cpu();
return best && (best->ebx & bit(X86_FEATURE_SMEP));
}
+static inline bool guest_cpuid_has_smap(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpuid_entry2 *best;
+
+ best = kvm_find_cpuid_entry(vcpu, 7, 0);
+ return best && (best->ebx & bit(X86_FEATURE_SMAP));
+}
+
static inline bool guest_cpuid_has_fsgsbase(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid_entry2 *best;
}
}
-static void update_permission_bitmask(struct kvm_vcpu *vcpu,
+void update_permission_bitmask(struct kvm_vcpu *vcpu,
struct kvm_mmu *mmu, bool ept)
{
unsigned bit, byte, pfec;
u8 map;
- bool fault, x, w, u, wf, uf, ff, smep;
+ bool fault, x, w, u, wf, uf, ff, smapf, cr4_smap, cr4_smep, smap = 0;
- smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP);
+ cr4_smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP);
+ cr4_smap = kvm_read_cr4_bits(vcpu, X86_CR4_SMAP);
for (byte = 0; byte < ARRAY_SIZE(mmu->permissions); ++byte) {
pfec = byte << 1;
map = 0;
wf = pfec & PFERR_WRITE_MASK;
uf = pfec & PFERR_USER_MASK;
ff = pfec & PFERR_FETCH_MASK;
+ /*
+ * PFERR_RSVD_MASK bit is set in PFEC if the access is not
+ * subject to SMAP restrictions, and cleared otherwise. The
+ * bit is only meaningful if the SMAP bit is set in CR4.
+ */
+ smapf = !(pfec & PFERR_RSVD_MASK);
for (bit = 0; bit < 8; ++bit) {
x = bit & ACC_EXEC_MASK;
w = bit & ACC_WRITE_MASK;
/* Allow supervisor writes if !cr0.wp */
w |= !is_write_protection(vcpu) && !uf;
/* Disallow supervisor fetches of user code if cr4.smep */
- x &= !(smep && u && !uf);
+ x &= !(cr4_smep && u && !uf);
+
+ /*
+ * SMAP:kernel-mode data accesses from user-mode
+ * mappings should fault. A fault is considered
+ * as a SMAP violation if all of the following
+ * conditions are ture:
+ * - X86_CR4_SMAP is set in CR4
+ * - An user page is accessed
+ * - Page fault in kernel mode
+ * - if CPL = 3 or X86_EFLAGS_AC is clear
+ *
+ * Here, we cover the first three conditions.
+ * The fourth is computed dynamically in
+ * permission_fault() and is in smapf.
+ *
+ * Also, SMAP does not affect instruction
+ * fetches, add the !ff check here to make it
+ * clearer.
+ */
+ smap = cr4_smap && u && !uf && !ff;
} else
/* Not really needed: no U/S accesses on ept */
u = 1;
- fault = (ff && !x) || (uf && !u) || (wf && !w);
+ fault = (ff && !x) || (uf && !u) || (wf && !w) ||
+ (smapf && smap);
map |= fault << bit;
}
mmu->permissions[byte] = map;
#define PT_DIRECTORY_LEVEL 2
#define PT_PAGE_TABLE_LEVEL 1
-#define PFERR_PRESENT_MASK (1U << 0)
-#define PFERR_WRITE_MASK (1U << 1)
-#define PFERR_USER_MASK (1U << 2)
-#define PFERR_RSVD_MASK (1U << 3)
-#define PFERR_FETCH_MASK (1U << 4)
+#define PFERR_PRESENT_BIT 0
+#define PFERR_WRITE_BIT 1
+#define PFERR_USER_BIT 2
+#define PFERR_RSVD_BIT 3
+#define PFERR_FETCH_BIT 4
+
+#define PFERR_PRESENT_MASK (1U << PFERR_PRESENT_BIT)
+#define PFERR_WRITE_MASK (1U << PFERR_WRITE_BIT)
+#define PFERR_USER_MASK (1U << PFERR_USER_BIT)
+#define PFERR_RSVD_MASK (1U << PFERR_RSVD_BIT)
+#define PFERR_FETCH_MASK (1U << PFERR_FETCH_BIT)
int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]);
void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask);
void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context);
void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context,
bool execonly);
+void update_permission_bitmask(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
+ bool ept);
static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm)
{
* Will a fault with a given page-fault error code (pfec) cause a permission
* fault with the given access (in ACC_* format)?
*/
-static inline bool permission_fault(struct kvm_mmu *mmu, unsigned pte_access,
- unsigned pfec)
+static inline bool permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
+ unsigned pte_access, unsigned pfec)
{
- return (mmu->permissions[pfec >> 1] >> pte_access) & 1;
+ int cpl = kvm_x86_ops->get_cpl(vcpu);
+ unsigned long rflags = kvm_x86_ops->get_rflags(vcpu);
+
+ /*
+ * If CPL < 3, SMAP prevention are disabled if EFLAGS.AC = 1.
+ *
+ * If CPL = 3, SMAP applies to all supervisor-mode data accesses
+ * (these are implicit supervisor accesses) regardless of the value
+ * of EFLAGS.AC.
+ *
+ * This computes (cpl < 3) && (rflags & X86_EFLAGS_AC), leaving
+ * the result in X86_EFLAGS_AC. We then insert it in place of
+ * the PFERR_RSVD_MASK bit; this bit will always be zero in pfec,
+ * but it will be one in index if SMAP checks are being overridden.
+ * It is important to keep this branchless.
+ */
+ unsigned long smap = (cpl - 3) & (rflags & X86_EFLAGS_AC);
+ int index = (pfec >> 1) +
+ (smap >> (X86_EFLAGS_AC_BIT - PFERR_RSVD_BIT + 1));
+
+ return (mmu->permissions[index] >> pte_access) & 1;
}
void kvm_mmu_invalidate_zap_all_pages(struct kvm *kvm);
walker->ptes[walker->level - 1] = pte;
} while (!is_last_gpte(mmu, walker->level, pte));
- if (unlikely(permission_fault(mmu, pte_access, access))) {
+ if (unlikely(permission_fault(vcpu, mmu, pte_access, access))) {
errcode |= PFERR_PRESENT_MASK;
goto error;
}
hw_cr4 &= ~X86_CR4_PAE;
hw_cr4 |= X86_CR4_PSE;
/*
- * SMEP is disabled if CPU is in non-paging mode in
- * hardware. However KVM always uses paging mode to
+ * SMEP/SMAP is disabled if CPU is in non-paging mode
+ * in hardware. However KVM always uses paging mode to
* emulate guest non-paging mode with TDP.
- * To emulate this behavior, SMEP needs to be manually
- * disabled when guest switches to non-paging mode.
+ * To emulate this behavior, SMEP/SMAP needs to be
+ * manually disabled when guest switches to non-paging
+ * mode.
*/
- hw_cr4 &= ~X86_CR4_SMEP;
+ hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP);
} else if (!(cr4 & X86_CR4_PAE)) {
hw_cr4 &= ~X86_CR4_PAE;
}
if (!guest_cpuid_has_smep(vcpu) && (cr4 & X86_CR4_SMEP))
return 1;
+ if (!guest_cpuid_has_smap(vcpu) && (cr4 & X86_CR4_SMAP))
+ return 1;
+
if (!guest_cpuid_has_fsgsbase(vcpu) && (cr4 & X86_CR4_FSGSBASE))
return 1;
(!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE)))
kvm_mmu_reset_context(vcpu);
+ if ((cr4 ^ old_cr4) & X86_CR4_SMAP)
+ update_permission_bitmask(vcpu, vcpu->arch.walk_mmu, false);
+
if ((cr4 ^ old_cr4) & X86_CR4_OSXSAVE)
kvm_update_cpuid(vcpu);
{
struct timespec ts;
- WARN_ON(preemptible());
ktime_get_ts(&ts);
monotonic_to_bootbased(&ts);
return timespec_to_ns(&ts);
| (write ? PFERR_WRITE_MASK : 0);
if (vcpu_match_mmio_gva(vcpu, gva)
- && !permission_fault(vcpu->arch.walk_mmu, vcpu->arch.access, access)) {
+ && !permission_fault(vcpu, vcpu->arch.walk_mmu,
+ vcpu->arch.access, access)) {
*gpa = vcpu->arch.mmio_gfn << PAGE_SHIFT |
(gva & (PAGE_SIZE - 1));
trace_vcpu_match_mmio(gva, *gpa, write, false);
targets += $(uapisyshdr-y) $(syshdr-y)
+PHONY += all
all: $(addprefix $(uapi)/,$(uapisyshdr-y))
all: $(addprefix $(out)/,$(syshdr-y))
+ @:
350 i386 finit_module sys_finit_module
351 i386 sched_setattr sys_sched_setattr
352 i386 sched_getattr sys_sched_getattr
+353 i386 renameat2 sys_renameat2
HOST_EXTRACFLAGS += -I$(srctree)/tools/include
hostprogs-y += relocs
relocs-objs := relocs_32.o relocs_64.o relocs_common.o
+PHONY += relocs
relocs: $(obj)/relocs
+ @:
#ifdef BUILD_VDSO32
#include <asm/vdso32.h>
- .hpet_sect : {
- hpet_page = . - VDSO_OFFSET(VDSO_HPET_PAGE);
- } :text :hpet_sect
+ hpet_page = . - VDSO_OFFSET(VDSO_HPET_PAGE);
- .vvar_sect : {
- vvar = . - VDSO_OFFSET(VDSO_VVAR_PAGE);
+ vvar = . - VDSO_OFFSET(VDSO_VVAR_PAGE);
/* Place all vvars at the offsets in asm/vvar.h. */
#define EMIT_VVAR(name, offset) vvar_ ## name = vvar + offset;
#include <asm/vvar.h>
#undef __VVAR_KERNEL_LDS
#undef EMIT_VVAR
- } :text :vvar_sect
#endif
. = SIZEOF_HEADERS;
*/
. = ALIGN(0x100);
- .text : { *(.text*) } :text =0x90909090
+ .text : { *(.text*) } :text =0x90909090,
+
+ /*
+ * The comma above works around a bug in gold:
+ * https://sourceware.org/bugzilla/show_bug.cgi?id=16804
+ */
/DISCARD/ : {
*(.discard)
dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
note PT_NOTE FLAGS(4); /* PF_R */
eh_frame_hdr PT_GNU_EH_FRAME;
-#ifdef BUILD_VDSO32
- vvar_sect PT_NULL FLAGS(4); /* PF_R */
- hpet_sect PT_NULL FLAGS(4); /* PF_R */
-#endif
}
irq_ctx_init(cpu);
#else
clear_tsk_thread_flag(idle, TIF_FORK);
+#endif
per_cpu(kernel_stack, cpu) =
(unsigned long)task_stack_page(idle) -
KERNEL_STACK_OFFSET + THREAD_SIZE;
-#endif
+
xen_setup_runstate_info(cpu);
xen_setup_timer(cpu);
xen_init_lock_cpu(cpu);
printk(KERN_DEBUG "xen: PV spinlocks disabled\n");
return;
}
-
+ printk(KERN_DEBUG "xen: PV spinlocks enabled\n");
pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning);
pv_lock_ops.unlock_kick = xen_unlock_kick;
}
if (!xen_pvspin)
return 0;
+ if (!xen_domain())
+ return 0;
+
static_key_slow_inc(¶virt_ticketlocks_enabled);
return 0;
}
* stack state in whatever form its in, we keep things simple by only
* using a single register which is pushed/popped on the stack.
*/
+
+.macro POP_FS
+1:
+ popw %fs
+.pushsection .fixup, "ax"
+2: movw $0, (%esp)
+ jmp 1b
+.popsection
+ _ASM_EXTABLE(1b,2b)
+.endm
+
ENTRY(xen_iret)
/* test eflags for special cases */
testl $(X86_EFLAGS_VM | XEN_EFLAGS_NMI), 8(%esp)
push %eax
ESP_OFFSET=4 # bytes pushed onto stack
- /*
- * Store vcpu_info pointer for easy access. Do it this way to
- * avoid having to reload %fs
- */
+ /* Store vcpu_info pointer for easy access */
#ifdef CONFIG_SMP
- GET_THREAD_INFO(%eax)
- movl %ss:TI_cpu(%eax), %eax
- movl %ss:__per_cpu_offset(,%eax,4), %eax
- mov %ss:xen_vcpu(%eax), %eax
+ pushw %fs
+ movl $(__KERNEL_PERCPU), %eax
+ movl %eax, %fs
+ movl %fs:xen_vcpu, %eax
+ POP_FS
#else
movl %ss:xen_vcpu, %eax
#endif
obj-$(CONFIG_CONNECTOR) += connector/
# i810fb and intelfb depend on char/agp/
-obj-$(CONFIG_FB_I810) += video/i810/
-obj-$(CONFIG_FB_INTEL) += video/intelfb/
+obj-$(CONFIG_FB_I810) += video/fbdev/i810/
+obj-$(CONFIG_FB_INTEL) += video/fbdev/intelfb/
obj-$(CONFIG_PARPORT) += parport/
obj-y += base/ block/ misc/ mfd/ nfc/
#include "accommon.h"
#include "acdispat.h"
#include "acinterp.h"
+#include "amlcode.h"
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME("exfield")
+/* Local prototypes */
+static u32
+acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length);
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_get_serial_access_bytes
+ *
+ * PARAMETERS: accessor_type - The type of the protocol indicated by region
+ * field access attributes
+ * access_length - The access length of the region field
+ *
+ * RETURN: Decoded access length
+ *
+ * DESCRIPTION: This routine returns the length of the generic_serial_bus
+ * protocol bytes
+ *
+ ******************************************************************************/
+
+static u32
+acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length)
+{
+ u32 length;
+
+ switch (accessor_type) {
+ case AML_FIELD_ATTRIB_QUICK:
+
+ length = 0;
+ break;
+
+ case AML_FIELD_ATTRIB_SEND_RCV:
+ case AML_FIELD_ATTRIB_BYTE:
+
+ length = 1;
+ break;
+
+ case AML_FIELD_ATTRIB_WORD:
+ case AML_FIELD_ATTRIB_WORD_CALL:
+
+ length = 2;
+ break;
+
+ case AML_FIELD_ATTRIB_MULTIBYTE:
+ case AML_FIELD_ATTRIB_RAW_BYTES:
+ case AML_FIELD_ATTRIB_RAW_PROCESS:
+
+ length = access_length;
+ break;
+
+ case AML_FIELD_ATTRIB_BLOCK:
+ case AML_FIELD_ATTRIB_BLOCK_CALL:
+ default:
+
+ length = ACPI_GSBUS_BUFFER_SIZE;
+ break;
+ }
+
+ return (length);
+}
+
/*******************************************************************************
*
* FUNCTION: acpi_ex_read_data_from_field
* Buffer, depending on the size of the field.
*
******************************************************************************/
+
acpi_status
-acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
+acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state,
union acpi_operand_object *obj_desc,
union acpi_operand_object **ret_buffer_desc)
{
acpi_size length;
void *buffer;
u32 function;
+ u16 accessor_type;
ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc);
ACPI_READ | (obj_desc->field.attribute << 16);
} else if (obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_GSBUS) {
- length = ACPI_GSBUS_BUFFER_SIZE;
- function =
- ACPI_READ | (obj_desc->field.attribute << 16);
+ accessor_type = obj_desc->field.attribute;
+ length = acpi_ex_get_serial_access_length(accessor_type,
+ obj_desc->
+ field.
+ access_length);
+
+ /*
+ * Add additional 2 bytes for modeled generic_serial_bus data buffer:
+ * typedef struct {
+ * BYTEStatus; // Byte 0 of the data buffer
+ * BYTELength; // Byte 1 of the data buffer
+ * BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer,
+ * }
+ */
+ length += 2;
+ function = ACPI_READ | (accessor_type << 16);
} else { /* IPMI */
length = ACPI_IPMI_BUFFER_SIZE;
void *buffer;
union acpi_operand_object *buffer_desc;
u32 function;
+ u16 accessor_type;
ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc);
ACPI_WRITE | (obj_desc->field.attribute << 16);
} else if (obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_GSBUS) {
- length = ACPI_GSBUS_BUFFER_SIZE;
- function =
- ACPI_WRITE | (obj_desc->field.attribute << 16);
+ accessor_type = obj_desc->field.attribute;
+ length = acpi_ex_get_serial_access_length(accessor_type,
+ obj_desc->
+ field.
+ access_length);
+
+ /*
+ * Add additional 2 bytes for modeled generic_serial_bus data buffer:
+ * typedef struct {
+ * BYTEStatus; // Byte 0 of the data buffer
+ * BYTELength; // Byte 1 of the data buffer
+ * BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer,
+ * }
+ */
+ length += 2;
+ function = ACPI_WRITE | (accessor_type << 16);
} else { /* IPMI */
length = ACPI_IPMI_BUFFER_SIZE;
break;
default:
- acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type);
- ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY;
- goto err;
+ acpi_handle_debug(handle, "Unknown event type 0x%x\n", type);
+ break;
}
adev = acpi_bus_get_acpi_device(handle);
config AHCI_IMX
tristate "Freescale i.MX AHCI SATA support"
- depends on MFD_SYSCON
+ depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST)
help
This option enables support for the Freescale i.MX SoC's
onboard AHCI SATA.
config AHCI_XGENE
tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support"
- depends on ARM64 || COMPILE_TEST
- select PHY_XGENE
+ depends on PHY_XGENE
help
This option enables support for APM X-Gene SoC SATA host controller.
#endif
static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports,
- struct ahci_host_priv *hpriv)
+ struct ahci_host_priv *hpriv)
{
- int nvec;
+ int rc, nvec;
if (hpriv->flags & AHCI_HFLAG_NO_MSI)
goto intx;
if (nvec < n_ports)
goto single_msi;
- nvec = pci_enable_msi_range(pdev, nvec, nvec);
- if (nvec == -ENOSPC)
+ rc = pci_enable_msi_exact(pdev, nvec);
+ if (rc == -ENOSPC)
goto single_msi;
- else if (nvec < 0)
+ else if (rc < 0)
goto intx;
+ /* fallback to single MSI mode if the controller enforced MRSM mode */
+ if (readl(hpriv->mmio + HOST_CTL) & HOST_MRSM) {
+ pci_disable_msi(pdev);
+ printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n");
+ goto single_msi;
+ }
+
return nvec;
single_msi:
return rc;
for (i = 0; i < host->n_ports; i++) {
- const char* desc;
struct ahci_port_priv *pp = host->ports[i]->private_data;
- /* pp is NULL for dummy ports */
- if (pp)
- desc = pp->irq_desc;
- else
- desc = dev_driver_string(host->dev);
+ /* Do not receive interrupts sent by dummy ports */
+ if (!pp) {
+ disable_irq(irq + i);
+ continue;
+ }
- rc = devm_request_threaded_irq(host->dev,
- irq + i, ahci_hw_interrupt, ahci_thread_fn, IRQF_SHARED,
- desc, host->ports[i]);
+ rc = devm_request_threaded_irq(host->dev, irq + i,
+ ahci_hw_interrupt,
+ ahci_thread_fn, IRQF_SHARED,
+ pp->irq_desc, host->ports[i]);
if (rc)
goto out_free_irqs;
}
/* HOST_CTL bits */
HOST_RESET = (1 << 0), /* reset controller; self-clear */
HOST_IRQ_EN = (1 << 1), /* global IRQ enable */
+ HOST_MRSM = (1 << 2), /* MSI Revert to Single Message */
HOST_AHCI_EN = (1 << 31), /* AHCI enabled */
/* HOST_CAP bits */
{ "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER },
/* devices that don't properly handle queued TRIM commands */
- { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
- { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
+ { "Micron_M500*", "MU0[1-4]*", ATA_HORKAGE_NO_NCQ_TRIM, },
+ { "Crucial_CT???M500SSD*", "MU0[1-4]*", ATA_HORKAGE_NO_NCQ_TRIM, },
+ { "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
+ { "Crucial_CT???M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
/*
* Some WD SATA-I drives spin up and down erratically when the link
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
{
struct ata_queued_cmd *qc = NULL;
- unsigned int i;
+ unsigned int i, tag;
/* no command while frozen */
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
return NULL;
- /* the last tag is reserved for internal command. */
- for (i = 0; i < ATA_MAX_QUEUE - 1; i++)
- if (!test_and_set_bit(i, &ap->qc_allocated)) {
- qc = __ata_qc_from_tag(ap, i);
+ for (i = 0; i < ATA_MAX_QUEUE; i++) {
+ tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
+
+ /* the last tag is reserved for internal command. */
+ if (tag == ATA_TAG_INTERNAL)
+ continue;
+
+ if (!test_and_set_bit(tag, &ap->qc_allocated)) {
+ qc = __ata_qc_from_tag(ap, tag);
+ qc->tag = tag;
+ ap->last_tag = tag;
break;
}
-
- if (qc)
- qc->tag = i;
+ }
return qc;
}
cf_card_detect(acdev, 0);
- return ata_host_activate(host, acdev->irq, irq_handler, 0,
- &arasan_cf_sht);
+ ret = ata_host_activate(host, acdev->irq, irq_handler, 0,
+ &arasan_cf_sht);
+ if (!ret)
+ return 0;
+ cf_exit(acdev);
free_clk:
clk_put(acdev->clk);
return ret;
host->private_data = info;
- return ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0,
- gpio_is_valid(irq) ? ata_sff_interrupt : NULL,
- irq_flags, &pata_at91_sht);
+ ret = ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0,
+ gpio_is_valid(irq) ? ata_sff_interrupt : NULL,
+ irq_flags, &pata_at91_sht);
+ if (ret)
+ goto err_put;
- if (!ret)
- return 0;
+ return 0;
err_put:
clk_put(info->mck);
platform_set_drvdata(pdev, host);
- return ata_host_activate(host, info->irq,
- info->irq ? pata_s3c_irq : NULL,
- 0, &pata_s3c_sht);
+ ret = ata_host_activate(host, info->irq,
+ info->irq ? pata_s3c_irq : NULL,
+ 0, &pata_s3c_sht);
+ if (ret)
+ goto stop_clk;
+
+ return 0;
stop_clk:
clk_disable(info->clk);
}
EXPORT_SYMBOL_GPL(device_remove_bin_file);
-/**
- * device_schedule_callback_owner - helper to schedule a callback for a device
- * @dev: device.
- * @func: callback function to invoke later.
- * @owner: module owning the callback routine
- *
- * Attribute methods must not unregister themselves or their parent device
- * (which would amount to the same thing). Attempts to do so will deadlock,
- * since unregistration is mutually exclusive with driver callbacks.
- *
- * Instead methods can call this routine, which will attempt to allocate
- * and schedule a workqueue request to call back @func with @dev as its
- * argument in the workqueue's process context. @dev will be pinned until
- * @func returns.
- *
- * This routine is usually called via the inline device_schedule_callback(),
- * which automatically sets @owner to THIS_MODULE.
- *
- * Returns 0 if the request was submitted, -ENOMEM if storage could not
- * be allocated, -ENODEV if a reference to @owner isn't available.
- *
- * NOTE: This routine won't work if CONFIG_SYSFS isn't set! It uses an
- * underlying sysfs routine (since it is intended for use by attribute
- * methods), and if sysfs isn't available you'll get nothing but -ENOSYS.
- */
-int device_schedule_callback_owner(struct device *dev,
- void (*func)(struct device *), struct module *owner)
-{
- return sysfs_schedule_callback(&dev->kobj,
- (void (*)(void *)) func, dev, owner);
-}
-EXPORT_SYMBOL_GPL(device_schedule_callback_owner);
-
static void klist_children_get(struct klist_node *n)
{
struct device_private *p = to_device_private_parent(n);
return;
}
- pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev),
- __func__, dev->driver->name);
+ pr_debug("driver: '%s': %s: bound to device '%s'\n", dev->driver->name,
+ __func__, dev_name(dev));
klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
WARN_ON(rc);
}
EXPORT_SYMBOL_GPL(devm_kfree);
+
+/**
+ * devm_kmemdup - Resource-managed kmemdup
+ * @dev: Device this memory belongs to
+ * @src: Memory region to duplicate
+ * @len: Memory region length
+ * @gfp: GFP mask to use
+ *
+ * Duplicate region of a memory using resource managed kmalloc
+ */
+void *devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp)
+{
+ void *p;
+
+ p = devm_kmalloc(dev, len, gfp);
+ if (p)
+ memcpy(p, src, len);
+
+ return p;
+}
+EXPORT_SYMBOL_GPL(devm_kmemdup);
static ssize_t show_##name(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
- unsigned int cpu = dev->id; \
- return sprintf(buf, "%d\n", topology_##name(cpu)); \
+ return sprintf(buf, "%d\n", topology_##name(dev->id)); \
}
#if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \
source "drivers/tty/serial/Kconfig"
config TTY_PRINTK
- bool "TTY driver to output user messages via printk"
+ tristate "TTY driver to output user messages via printk"
depends on EXPERT && TTY
default n
---help---
}
bcm2835_rng_ops.priv = (unsigned long)rng_base;
+ /* set warm-up count & enable */
+ __raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS);
+ __raw_writel(RNG_RBGEN, rng_base + RNG_CTRL);
+
/* register driver */
err = hwrng_register(&bcm2835_rng_ops);
if (err) {
dev_err(dev, "hwrng registration failed\n");
iounmap(rng_base);
- } else {
+ } else
dev_info(dev, "hwrng registered\n");
- /* set warm-up count & enable */
- __raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS);
- __raw_writel(RNG_RBGEN, rng_base + RNG_CTRL);
- }
return err;
}
Currently, only KCS and SMIC are supported. If
you are using IPMI, you should probably say "y" here.
+config IPMI_SI_PROBE_DEFAULTS
+ bool 'Probe for all possible IPMI system interfaces by default'
+ default n
+ depends on IPMI_SI
+ help
+ Modern systems will usually expose IPMI interfaces via a discoverable
+ firmware mechanism such as ACPI or DMI. Older systems do not, and so
+ the driver is forced to probe hardware manually. This may cause boot
+ delays. Say "n" here to disable this manual probing. IPMI will then
+ only be available on older systems if the "ipmi_si_intf.trydefaults=1"
+ boot argument is passed.
+
config IPMI_WATCHDOG
tristate 'IPMI Watchdog Timer'
help
static inline int read_all_bytes(struct si_sm_data *bt)
{
- unsigned char i;
+ unsigned int i;
/*
* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
if (!GET_STATUS_OBF(status)) {
kcs->obf_timeout -= time;
if (kcs->obf_timeout < 0) {
- start_error_recovery(kcs, "OBF not ready in time");
- return 1;
+ kcs->obf_timeout = OBF_RETRY_TIMEOUT;
+ start_error_recovery(kcs, "OBF not ready in time");
+ return 1;
}
return 0;
}
static int ipmi_init_msghandler(void);
static void smi_recv_tasklet(unsigned long);
static void handle_new_recv_msgs(ipmi_smi_t intf);
+static void need_waiter(ipmi_smi_t intf);
static int initialized;
*/
#define MAX_MSG_TIMEOUT 60000
+/* Call every ~1000 ms. */
+#define IPMI_TIMEOUT_TIME 1000
+
+/* How many jiffies does it take to get to the timeout time. */
+#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000)
+
+/*
+ * Request events from the queue every second (this is the number of
+ * IPMI_TIMEOUT_TIMES between event requests). Hopefully, in the
+ * future, IPMI will add a way to know immediately if an event is in
+ * the queue and this silliness can go away.
+ */
+#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
+
/*
* The main "user" data structure.
*/
struct ipmi_user {
struct list_head link;
- /* Set to "0" when the user is destroyed. */
- int valid;
+ /* Set to false when the user is destroyed. */
+ bool valid;
struct kref refcount;
ipmi_smi_t intf;
/* Does this interface receive IPMI events? */
- int gets_events;
+ bool gets_events;
};
struct cmd_rcvr {
unsigned int waiting_events_count; /* How many events in queue? */
char delivering_events;
char event_msg_printed;
+ atomic_t event_waiters;
+ unsigned int ticks_to_req_ev;
+ int last_needs_timer;
/*
* The event receiver for my BMC, only really used at panic
/* For handling of maintenance mode. */
int maintenance_mode;
- int maintenance_mode_enable;
+ bool maintenance_mode_enable;
int auto_maintenance_timeout;
spinlock_t maintenance_mode_lock; /* Used in a timer... */
static LIST_HEAD(smi_watchers);
static DEFINE_MUTEX(smi_watchers_mutex);
-
#define ipmi_inc_stat(intf, stat) \
atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
#define ipmi_get_stat(intf, stat) \
*seq = i;
*seqid = intf->seq_table[i].seqid;
intf->curr_seq = (i+1)%IPMI_IPMB_NUM_SEQ;
+ need_waiter(intf);
} else {
rv = -EAGAIN;
}
new_user->handler = handler;
new_user->handler_data = handler_data;
new_user->intf = intf;
- new_user->gets_events = 0;
+ new_user->gets_events = false;
if (!try_module_get(intf->handlers->owner)) {
rv = -ENODEV;
*/
mutex_unlock(&ipmi_interfaces_mutex);
- new_user->valid = 1;
+ new_user->valid = true;
spin_lock_irqsave(&intf->seq_lock, flags);
list_add_rcu(&new_user->link, &intf->users);
spin_unlock_irqrestore(&intf->seq_lock, flags);
+ if (handler->ipmi_watchdog_pretimeout) {
+ /* User wants pretimeouts, so make sure to watch for them. */
+ if (atomic_inc_return(&intf->event_waiters) == 1)
+ need_waiter(intf);
+ }
*user = new_user;
return 0;
struct cmd_rcvr *rcvr;
struct cmd_rcvr *rcvrs = NULL;
- user->valid = 0;
+ user->valid = false;
+
+ if (user->handler->ipmi_watchdog_pretimeout)
+ atomic_dec(&intf->event_waiters);
+
+ if (user->gets_events)
+ atomic_dec(&intf->event_waiters);
/* Remove the user from the interface's sequence table. */
spin_lock_irqsave(&intf->seq_lock, flags);
if (intf->maintenance_mode != mode) {
switch (mode) {
case IPMI_MAINTENANCE_MODE_AUTO:
- intf->maintenance_mode = mode;
intf->maintenance_mode_enable
= (intf->auto_maintenance_timeout > 0);
break;
case IPMI_MAINTENANCE_MODE_OFF:
- intf->maintenance_mode = mode;
- intf->maintenance_mode_enable = 0;
+ intf->maintenance_mode_enable = false;
break;
case IPMI_MAINTENANCE_MODE_ON:
- intf->maintenance_mode = mode;
- intf->maintenance_mode_enable = 1;
+ intf->maintenance_mode_enable = true;
break;
default:
rv = -EINVAL;
goto out_unlock;
}
+ intf->maintenance_mode = mode;
maintenance_mode_update(intf);
}
}
EXPORT_SYMBOL(ipmi_set_maintenance_mode);
-int ipmi_set_gets_events(ipmi_user_t user, int val)
+int ipmi_set_gets_events(ipmi_user_t user, bool val)
{
unsigned long flags;
ipmi_smi_t intf = user->intf;
INIT_LIST_HEAD(&msgs);
spin_lock_irqsave(&intf->events_lock, flags);
+ if (user->gets_events == val)
+ goto out;
+
user->gets_events = val;
+ if (val) {
+ if (atomic_inc_return(&intf->event_waiters) == 1)
+ need_waiter(intf);
+ } else {
+ atomic_dec(&intf->event_waiters);
+ }
+
if (intf->delivering_events)
/*
* Another thread is delivering events for this, so
goto out_unlock;
}
+ if (atomic_inc_return(&intf->event_waiters) == 1)
+ need_waiter(intf);
+
list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
out_unlock:
mutex_unlock(&intf->cmd_rcvrs_mutex);
synchronize_rcu();
while (rcvrs) {
+ atomic_dec(&intf->event_waiters);
rcvr = rcvrs;
rcvrs = rcvr->next;
kfree(rcvr);
= IPMI_MAINTENANCE_MODE_TIMEOUT;
if (!intf->maintenance_mode
&& !intf->maintenance_mode_enable) {
- intf->maintenance_mode_enable = 1;
+ intf->maintenance_mode_enable = true;
maintenance_mode_update(intf);
}
spin_unlock_irqrestore(&intf->maintenance_mode_lock,
(unsigned long) intf);
atomic_set(&intf->watchdog_pretimeouts_to_deliver, 0);
spin_lock_init(&intf->events_lock);
+ atomic_set(&intf->event_waiters, 0);
+ intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
INIT_LIST_HEAD(&intf->waiting_events);
intf->waiting_events_count = 0;
mutex_init(&intf->cmd_rcvrs_mutex);
static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
struct list_head *timeouts, long timeout_period,
- int slot, unsigned long *flags)
+ int slot, unsigned long *flags,
+ unsigned int *waiting_msgs)
{
struct ipmi_recv_msg *msg;
struct ipmi_smi_handlers *handlers;
return;
ent->timeout -= timeout_period;
- if (ent->timeout > 0)
+ if (ent->timeout > 0) {
+ (*waiting_msgs)++;
return;
+ }
if (ent->retries_left == 0) {
/* The message has used all its retries. */
struct ipmi_smi_msg *smi_msg;
/* More retries, send again. */
+ (*waiting_msgs)++;
+
/*
* Start with the max timer, set to normal timer after
* the message is sent.
}
}
-static void ipmi_timeout_handler(long timeout_period)
+static unsigned int ipmi_timeout_handler(ipmi_smi_t intf, long timeout_period)
{
- ipmi_smi_t intf;
struct list_head timeouts;
struct ipmi_recv_msg *msg, *msg2;
unsigned long flags;
int i;
+ unsigned int waiting_msgs = 0;
- rcu_read_lock();
- list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
- tasklet_schedule(&intf->recv_tasklet);
-
- /*
- * Go through the seq table and find any messages that
- * have timed out, putting them in the timeouts
- * list.
- */
- INIT_LIST_HEAD(&timeouts);
- spin_lock_irqsave(&intf->seq_lock, flags);
- for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
- check_msg_timeout(intf, &(intf->seq_table[i]),
- &timeouts, timeout_period, i,
- &flags);
- spin_unlock_irqrestore(&intf->seq_lock, flags);
+ /*
+ * Go through the seq table and find any messages that
+ * have timed out, putting them in the timeouts
+ * list.
+ */
+ INIT_LIST_HEAD(&timeouts);
+ spin_lock_irqsave(&intf->seq_lock, flags);
+ for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
+ check_msg_timeout(intf, &(intf->seq_table[i]),
+ &timeouts, timeout_period, i,
+ &flags, &waiting_msgs);
+ spin_unlock_irqrestore(&intf->seq_lock, flags);
- list_for_each_entry_safe(msg, msg2, &timeouts, link)
- deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE);
+ list_for_each_entry_safe(msg, msg2, &timeouts, link)
+ deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE);
- /*
- * Maintenance mode handling. Check the timeout
- * optimistically before we claim the lock. It may
- * mean a timeout gets missed occasionally, but that
- * only means the timeout gets extended by one period
- * in that case. No big deal, and it avoids the lock
- * most of the time.
- */
+ /*
+ * Maintenance mode handling. Check the timeout
+ * optimistically before we claim the lock. It may
+ * mean a timeout gets missed occasionally, but that
+ * only means the timeout gets extended by one period
+ * in that case. No big deal, and it avoids the lock
+ * most of the time.
+ */
+ if (intf->auto_maintenance_timeout > 0) {
+ spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
if (intf->auto_maintenance_timeout > 0) {
- spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
- if (intf->auto_maintenance_timeout > 0) {
- intf->auto_maintenance_timeout
- -= timeout_period;
- if (!intf->maintenance_mode
- && (intf->auto_maintenance_timeout <= 0)) {
- intf->maintenance_mode_enable = 0;
- maintenance_mode_update(intf);
- }
+ intf->auto_maintenance_timeout
+ -= timeout_period;
+ if (!intf->maintenance_mode
+ && (intf->auto_maintenance_timeout <= 0)) {
+ intf->maintenance_mode_enable = false;
+ maintenance_mode_update(intf);
}
- spin_unlock_irqrestore(&intf->maintenance_mode_lock,
- flags);
}
+ spin_unlock_irqrestore(&intf->maintenance_mode_lock,
+ flags);
}
- rcu_read_unlock();
+
+ tasklet_schedule(&intf->recv_tasklet);
+
+ return waiting_msgs;
}
-static void ipmi_request_event(void)
+static void ipmi_request_event(ipmi_smi_t intf)
{
- ipmi_smi_t intf;
struct ipmi_smi_handlers *handlers;
- rcu_read_lock();
- /*
- * Called from the timer, no need to check if handlers is
- * valid.
- */
- list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
- /* No event requests when in maintenance mode. */
- if (intf->maintenance_mode_enable)
- continue;
+ /* No event requests when in maintenance mode. */
+ if (intf->maintenance_mode_enable)
+ return;
- handlers = intf->handlers;
- if (handlers)
- handlers->request_events(intf->send_info);
- }
- rcu_read_unlock();
+ handlers = intf->handlers;
+ if (handlers)
+ handlers->request_events(intf->send_info);
}
static struct timer_list ipmi_timer;
-/* Call every ~1000 ms. */
-#define IPMI_TIMEOUT_TIME 1000
-
-/* How many jiffies does it take to get to the timeout time. */
-#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000)
-
-/*
- * Request events from the queue every second (this is the number of
- * IPMI_TIMEOUT_TIMES between event requests). Hopefully, in the
- * future, IPMI will add a way to know immediately if an event is in
- * the queue and this silliness can go away.
- */
-#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
-
static atomic_t stop_operation;
-static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
static void ipmi_timeout(unsigned long data)
{
+ ipmi_smi_t intf;
+ int nt = 0;
+
if (atomic_read(&stop_operation))
return;
- ticks_to_req_ev--;
- if (ticks_to_req_ev == 0) {
- ipmi_request_event();
- ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
- }
+ rcu_read_lock();
+ list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+ int lnt = 0;
+
+ if (atomic_read(&intf->event_waiters)) {
+ intf->ticks_to_req_ev--;
+ if (intf->ticks_to_req_ev == 0) {
+ ipmi_request_event(intf);
+ intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
+ }
+ lnt++;
+ }
- ipmi_timeout_handler(IPMI_TIMEOUT_TIME);
+ lnt += ipmi_timeout_handler(intf, IPMI_TIMEOUT_TIME);
- mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
+ lnt = !!lnt;
+ if (lnt != intf->last_needs_timer &&
+ intf->handlers->set_need_watch)
+ intf->handlers->set_need_watch(intf->send_info, lnt);
+ intf->last_needs_timer = lnt;
+
+ nt += lnt;
+ }
+ rcu_read_unlock();
+
+ if (nt)
+ mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
}
+static void need_waiter(ipmi_smi_t intf)
+{
+ /* Racy, but worst case we start the timer twice. */
+ if (!timer_pending(&ipmi_timer))
+ mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
+}
static atomic_t smi_msg_inuse_count = ATOMIC_INIT(0);
static atomic_t recv_msg_inuse_count = ATOMIC_INIT(0);
unsigned char msg_flags;
/* Does the BMC have an event buffer? */
- char has_event_buffer;
+ bool has_event_buffer;
/*
* If set to true, this will request events the next time the
* call. Generally used after a panic to make sure stuff goes
* out.
*/
- int run_to_completion;
+ bool run_to_completion;
/* The I/O port of an SI interface. */
int port;
/* The timer for this si. */
struct timer_list si_timer;
+ /* This flag is set, if the timer is running (timer_pending() isn't enough) */
+ bool timer_running;
+
/* The time (in jiffies) the last timeout occurred at. */
unsigned long last_timeout_jiffies;
/* Used to gracefully stop the timer without race conditions. */
atomic_t stop_operation;
+ /* Are we waiting for the events, pretimeouts, received msgs? */
+ atomic_t need_watch;
+
/*
* The driver will disable interrupts when it gets into a
* situation where it cannot handle messages due to lack of
* memory. Once that situation clears up, it will re-enable
* interrupts.
*/
- int interrupt_disabled;
+ bool interrupt_disabled;
/* From the get device id response... */
struct ipmi_device_id device_id;
* True if we allocated the device, false if it came from
* someplace else (like PCI).
*/
- int dev_registered;
+ bool dev_registered;
/* Slave address, could be reported from DMI. */
unsigned char slave_addr;
static int force_kipmid[SI_MAX_PARMS];
static int num_force_kipmid;
#ifdef CONFIG_PCI
-static int pci_registered;
+static bool pci_registered;
#endif
#ifdef CONFIG_ACPI
-static int pnp_registered;
+static bool pnp_registered;
#endif
#ifdef CONFIG_PARISC
-static int parisc_registered;
+static bool parisc_registered;
#endif
static unsigned int kipmid_max_busy_us[SI_MAX_PARMS];
static int num_max_busy_us;
-static int unload_when_empty = 1;
+static bool unload_when_empty = true;
static int add_smi(struct smi_info *smi);
static int try_smi_init(struct smi_info *smi);
smi_info->si_state = SI_CLEARING_FLAGS;
}
+static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val)
+{
+ smi_info->last_timeout_jiffies = jiffies;
+ mod_timer(&smi_info->si_timer, new_val);
+ smi_info->timer_running = true;
+}
+
/*
* When we have a situtaion where we run out of memory and cannot
* allocate messages, we just leave them in the BMC and run the system
{
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
start_disable_irq(smi_info);
- smi_info->interrupt_disabled = 1;
+ smi_info->interrupt_disabled = true;
if (!atomic_read(&smi_info->stop_operation))
- mod_timer(&smi_info->si_timer,
- jiffies + SI_TIMEOUT_JIFFIES);
+ smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
}
}
{
if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
start_enable_irq(smi_info);
- smi_info->interrupt_disabled = 0;
+ smi_info->interrupt_disabled = false;
}
}
dev_warn(smi_info->dev,
"Maybe ok, but ipmi might run very slowly.\n");
} else
- smi_info->interrupt_disabled = 0;
+ smi_info->interrupt_disabled = false;
smi_info->si_state = SI_NORMAL;
break;
}
return si_sm_result;
}
+static void check_start_timer_thread(struct smi_info *smi_info)
+{
+ if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) {
+ smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
+
+ if (smi_info->thread)
+ wake_up_process(smi_info->thread);
+
+ start_next_msg(smi_info);
+ smi_event_handler(smi_info, 0);
+ }
+}
+
static void sender(void *send_info,
struct ipmi_smi_msg *msg,
int priority)
else
list_add_tail(&msg->link, &smi_info->xmit_msgs);
- if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) {
- /*
- * last_timeout_jiffies is updated here to avoid
- * smi_timeout() handler passing very large time_diff
- * value to smi_event_handler() that causes
- * the send command to abort.
- */
- smi_info->last_timeout_jiffies = jiffies;
-
- mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
-
- if (smi_info->thread)
- wake_up_process(smi_info->thread);
-
- start_next_msg(smi_info);
- smi_event_handler(smi_info, 0);
- }
+ check_start_timer_thread(smi_info);
spin_unlock_irqrestore(&smi_info->si_lock, flags);
}
-static void set_run_to_completion(void *send_info, int i_run_to_completion)
+static void set_run_to_completion(void *send_info, bool i_run_to_completion)
{
struct smi_info *smi_info = send_info;
enum si_sm_result result;
spin_lock_irqsave(&(smi_info->si_lock), flags);
smi_result = smi_event_handler(smi_info, 0);
+
+ /*
+ * If the driver is doing something, there is a possible
+ * race with the timer. If the timer handler see idle,
+ * and the thread here sees something else, the timer
+ * handler won't restart the timer even though it is
+ * required. So start it here if necessary.
+ */
+ if (smi_result != SI_SM_IDLE && !smi_info->timer_running)
+ smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
+
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
busy_wait = ipmi_thread_busy_wait(smi_result, smi_info,
&busy_until);
; /* do nothing */
else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait)
schedule();
- else if (smi_result == SI_SM_IDLE)
- schedule_timeout_interruptible(100);
- else
+ else if (smi_result == SI_SM_IDLE) {
+ if (atomic_read(&smi_info->need_watch)) {
+ schedule_timeout_interruptible(100);
+ } else {
+ /* Wait to be woken up when we are needed. */
+ __set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ }
+ } else
schedule_timeout_interruptible(1);
}
return 0;
{
struct smi_info *smi_info = send_info;
unsigned long flags = 0;
- int run_to_completion = smi_info->run_to_completion;
+ bool run_to_completion = smi_info->run_to_completion;
/*
* Make sure there is some delay in the poll loop so we can
atomic_set(&smi_info->req_events, 1);
}
+static void set_need_watch(void *send_info, bool enable)
+{
+ struct smi_info *smi_info = send_info;
+ unsigned long flags;
+
+ atomic_set(&smi_info->need_watch, enable);
+ spin_lock_irqsave(&smi_info->si_lock, flags);
+ check_start_timer_thread(smi_info);
+ spin_unlock_irqrestore(&smi_info->si_lock, flags);
+}
+
static int initialized;
static void smi_timeout(unsigned long data)
* SI_USEC_PER_JIFFY);
smi_result = smi_event_handler(smi_info, time_diff);
- spin_unlock_irqrestore(&(smi_info->si_lock), flags);
-
- smi_info->last_timeout_jiffies = jiffies_now;
-
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
/* Running with interrupts, only do long timeouts. */
timeout = jiffies + SI_TIMEOUT_JIFFIES;
do_mod_timer:
if (smi_result != SI_SM_IDLE)
- mod_timer(&(smi_info->si_timer), timeout);
+ smi_mod_timer(smi_info, timeout);
+ else
+ smi_info->timer_running = false;
+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
}
static irqreturn_t si_irq_handler(int irq, void *data)
/* Set up the timer that drives the interface. */
setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
- new_smi->last_timeout_jiffies = jiffies;
- mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
+ smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES);
/*
* Check if the user forcefully enabled the daemon.
return 0;
}
-static void set_maintenance_mode(void *send_info, int enable)
+static void set_maintenance_mode(void *send_info, bool enable)
{
struct smi_info *smi_info = send_info;
.get_smi_info = get_smi_info,
.sender = sender,
.request_events = request_events,
+ .set_need_watch = set_need_watch,
.set_maintenance_mode = set_maintenance_mode,
.set_run_to_completion = set_run_to_completion,
.poll = poll,
#ifdef CONFIG_PCI
static bool si_trypci = 1;
#endif
-static bool si_trydefaults = 1;
+static bool si_trydefaults = IS_ENABLED(CONFIG_IPMI_SI_PROBE_DEFAULTS);
static char *si_type[SI_MAX_PARMS];
#define MAX_SI_TYPE_STR 30
static char si_type_str[MAX_SI_TYPE_STR];
MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or"
" disabled(0). Normally the IPMI driver auto-detects"
" this, but the value may be overridden by this parm.");
-module_param(unload_when_empty, int, 0);
+module_param(unload_when_empty, bool, 0);
MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are"
" specified or found, default is 1. Setting to 0"
" is useful for hot add of devices using hotmod.");
INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs));
new_smi->curr_msg = NULL;
atomic_set(&new_smi->req_events, 0);
- new_smi->run_to_completion = 0;
+ new_smi->run_to_completion = false;
for (i = 0; i < SI_NUM_STATS; i++)
atomic_set(&new_smi->stats[i], 0);
- new_smi->interrupt_disabled = 1;
+ new_smi->interrupt_disabled = true;
atomic_set(&new_smi->stop_operation, 0);
+ atomic_set(&new_smi->need_watch, 0);
new_smi->intf_num = smi_num;
smi_num++;
rv = try_enable_event_buffer(new_smi);
if (rv == 0)
- new_smi->has_event_buffer = 1;
+ new_smi->has_event_buffer = true;
/*
* Start clearing the flags before we enable interrupts or the
rv);
goto out_err;
}
- new_smi->dev_registered = 1;
+ new_smi->dev_registered = true;
}
rv = ipmi_register_smi(&handlers,
wait_for_timer_and_thread(new_smi);
out_err:
- new_smi->interrupt_disabled = 1;
+ new_smi->interrupt_disabled = true;
if (new_smi->intf) {
ipmi_unregister_smi(new_smi->intf);
if (new_smi->dev_registered) {
platform_device_unregister(new_smi->pdev);
- new_smi->dev_registered = 0;
+ new_smi->dev_registered = false;
}
return rv;
printk(KERN_ERR PFX "Unable to register "
"PCI driver: %d\n", rv);
else
- pci_registered = 1;
+ pci_registered = true;
}
#endif
#ifdef CONFIG_ACPI
if (si_tryacpi) {
pnp_register_driver(&ipmi_pnp_driver);
- pnp_registered = 1;
+ pnp_registered = true;
}
#endif
#ifdef CONFIG_PARISC
register_parisc_driver(&ipmi_parisc_driver);
- parisc_registered = 1;
+ parisc_registered = true;
/* poking PC IO addresses will crash machine, don't do it */
si_trydefaults = 0;
#endif
This driver may be built as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
- The module will be called synclinkmp. If you want to do that, say M
+ The module will be called synclink_cs. If you want to do that, say M
here.
config CARDMAN_4000
#include <linux/device.h>
#include <linux/serial.h>
#include <linux/tty.h>
-#include <linux/export.h>
+#include <linux/module.h>
struct ttyprintk_port {
struct tty_port port;
return 0;
error:
- tty_unregister_driver(ttyprintk_driver);
put_tty_driver(ttyprintk_driver);
tty_port_destroy(&tpk_port.port);
- ttyprintk_driver = NULL;
return ret;
}
+
+static void __exit ttyprintk_exit(void)
+{
+ tty_unregister_driver(ttyprintk_driver);
+ put_tty_driver(ttyprintk_driver);
+ tty_port_destroy(&tpk_port.port);
+}
+
device_initcall(ttyprintk_init);
+module_exit(ttyprintk_exit);
+
+MODULE_LICENSE("GPL");
[tegra_clk_sdmmc2_8] = { .dt_id = TEGRA124_CLK_SDMMC2, .present = true },
[tegra_clk_i2s1] = { .dt_id = TEGRA124_CLK_I2S1, .present = true },
[tegra_clk_i2c1] = { .dt_id = TEGRA124_CLK_I2C1, .present = true },
- [tegra_clk_ndflash] = { .dt_id = TEGRA124_CLK_NDFLASH, .present = true },
[tegra_clk_sdmmc1_8] = { .dt_id = TEGRA124_CLK_SDMMC1, .present = true },
[tegra_clk_sdmmc4_8] = { .dt_id = TEGRA124_CLK_SDMMC4, .present = true },
[tegra_clk_pwm] = { .dt_id = TEGRA124_CLK_PWM, .present = true },
[tegra_clk_trace] = { .dt_id = TEGRA124_CLK_TRACE, .present = true },
[tegra_clk_soc_therm] = { .dt_id = TEGRA124_CLK_SOC_THERM, .present = true },
[tegra_clk_dtv] = { .dt_id = TEGRA124_CLK_DTV, .present = true },
- [tegra_clk_ndspeed] = { .dt_id = TEGRA124_CLK_NDSPEED, .present = true },
[tegra_clk_i2cslow] = { .dt_id = TEGRA124_CLK_I2CSLOW, .present = true },
[tegra_clk_dsib] = { .dt_id = TEGRA124_CLK_DSIB, .present = true },
[tegra_clk_tsec] = { .dt_id = TEGRA124_CLK_TSEC, .present = true },
[tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_3_MUX, .present = true },
[tegra_clk_dsia_mux] = { .dt_id = TEGRA124_CLK_DSIA_MUX, .present = true },
[tegra_clk_dsib_mux] = { .dt_id = TEGRA124_CLK_DSIB_MUX, .present = true },
- [tegra_clk_uarte] = { .dt_id = TEGRA124_CLK_UARTE, .present = true },
};
static struct tegra_devclk devclks[] __initdata = {
osc = kzalloc(sizeof(*osc), GFP_KERNEL);
if (!osc)
- goto error;
+ return;
osc->func = vexpress_config_func_get_by_node(node);
if (!osc->func) {
evt->set_mode = exynos4_tick_set_mode;
evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
evt->rating = 450;
- clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1),
- 0xf, 0x7fffffff);
exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
evt->irq);
return -EIO;
}
+ irq_force_affinity(mct_irqs[MCT_L0_IRQ + cpu], cpumask_of(cpu));
} else {
enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0);
}
+ clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1),
+ 0xf, 0x7fffffff);
return 0;
}
unsigned long action, void *hcpu)
{
struct mct_clock_event_device *mevt;
- unsigned int cpu;
/*
* Grab cpu pointer in each case to avoid spurious
mevt = this_cpu_ptr(&percpu_mct_tick);
exynos4_local_timer_setup(&mevt->evt);
break;
- case CPU_ONLINE:
- cpu = (unsigned long)hcpu;
- if (mct_int_type == MCT_INT_SPI)
- irq_set_affinity(mct_irqs[MCT_L0_IRQ + cpu],
- cpumask_of(cpu));
- break;
case CPU_DYING:
mevt = this_cpu_ptr(&percpu_mct_tick);
exynos4_local_timer_stop(&mevt->evt);
config ARM_HIGHBANK_CPUFREQ
tristate "Calxeda Highbank-based"
- depends on ARCH_HIGHBANK
- select GENERIC_CPUFREQ_CPU0
- select PM_OPP
- select REGULATOR
-
+ depends on ARCH_HIGHBANK && GENERIC_CPUFREQ_CPU0 && REGULATOR
default m
help
This adds the CPUFreq driver for Calxeda Highbank SoC
#include <asm/cputhreads.h>
#include <asm/reg.h>
+#include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */
#define POWERNV_MAX_PSTATES 256
per_cpu(cpu_data, i) = data;
policy->cpuinfo.transition_latency =
- (12 * NSEC_PER_SEC) / fsl_get_sys_freq();
+ (12ULL * NSEC_PER_SEC) / fsl_get_sys_freq();
of_node_put(np);
return 0;
policy->max = policy->cpuinfo.max_freq = 1000000;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->clk = clk_get(NULL, "MAIN_CLK");
- if (IS_ERR(policy->clk))
- return PTR_ERR(policy->clk);
- return 0;
+ return PTR_ERR_OR_ZERO(policy->clk);
}
static struct cpufreq_driver ucv2_driver = {
config TIMB_DMA
tristate "Timberdale FPGA DMA support"
- depends on MFD_TIMBERDALE || HAS_IOMEM
+ depends on MFD_TIMBERDALE
select DMA_ENGINE
help
Enable support for the Timberdale FPGA DMA engine.
echan->ecc->dummy_slot);
}
- edma_resume(echan->ch_num);
-
if (edesc->processed <= MAX_NR_SG) {
dev_dbg(dev, "first transfer starting %d\n", echan->ch_num);
edma_start(echan->ch_num);
+ } else {
+ dev_dbg(dev, "chan: %d: completed %d elements, resuming\n",
+ echan->ch_num, edesc->processed);
+ edma_resume(echan->ch_num);
}
/*
.remove = fsl_edma_remove,
};
-module_platform_driver(fsl_edma_driver);
+static int __init fsl_edma_init(void)
+{
+ return platform_driver_register(&fsl_edma_driver);
+}
+subsys_initcall(fsl_edma_init);
+
+static void __exit fsl_edma_exit(void)
+{
+ platform_driver_unregister(&fsl_edma_driver);
+}
+module_exit(fsl_edma_exit);
MODULE_ALIAS("platform:fsl-edma");
MODULE_DESCRIPTION("Freescale eDMA engine driver");
struct sirfsoc_dma *sdma = ofdma->of_dma_data;
unsigned int request = dma_spec->args[0];
- if (request > SIRFSOC_DMA_CHANNELS)
+ if (request >= SIRFSOC_DMA_CHANNELS)
return NULL;
return dma_get_slave_channel(&sdma->channels[request].chan);
* SPEAr platform SPI chipselect abstraction over gpiolib
*
* Copyright (C) 2012 ST Microelectronics
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
}
subsys_initcall(spics_gpio_init);
-MODULE_AUTHOR("Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_AUTHOR("Shiraz Hashim <shiraz.linux.kernel@gmail.com>");
MODULE_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction");
MODULE_LICENSE("GPL");
{
struct gpio_chip *chip = acpi_gpio->chip;
- if (!chip->dev || !chip->to_irq)
+ if (!chip->to_irq)
return;
INIT_LIST_HEAD(&acpi_gpio->events);
struct acpi_gpio_event *event, *ep;
struct gpio_chip *chip = acpi_gpio->chip;
- if (!chip->dev || !chip->to_irq)
+ if (!chip->to_irq)
return;
list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
if (function == ACPI_WRITE)
gpiod_set_raw_value(desc, !!((1 << i) & *value));
else
- *value |= gpiod_get_raw_value(desc) << i;
+ *value |= (u64)gpiod_get_raw_value(desc) << i;
}
out:
acpi_handle handle;
acpi_status status;
+ if (!chip || !chip->dev)
+ return;
+
handle = ACPI_HANDLE(chip->dev);
if (!handle)
return;
acpi_handle handle;
acpi_status status;
+ if (!chip || !chip->dev)
+ return;
+
handle = ACPI_HANDLE(chip->dev);
if (!handle)
return;
{
struct gpio_chip *chip = d->host_data;
- irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler);
irq_set_chip_data(irq, chip);
+ irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler);
#ifdef CONFIG_ARM
set_irq_flags(irq, IRQF_VALID);
#else
drm-usb-y := drm_usb.o
-drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o
+drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
for (loop = 0; loop < CBR_PASSNUM2; loop++) {
if ((data = cbr_test2(ast)) != 0) {
data2 &= data;
- if (!data)
+ if (!data2)
return 0;
break;
}
#include <linux/io.h>
#include <linux/fb.h>
+#include <linux/console.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
struct bochs_framebuffer gfb;
struct drm_fb_helper helper;
int size;
- int x1, y1, x2, y2; /* dirty rect */
- spinlock_t dirty_lock;
bool initialized;
} fb;
};
.dumb_destroy = drm_gem_dumb_destroy,
};
+/* ---------------------------------------------------------------------- */
+/* pm interface */
+
+static int bochs_pm_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct bochs_device *bochs = drm_dev->dev_private;
+
+ drm_kms_helper_poll_disable(drm_dev);
+
+ if (bochs->fb.initialized) {
+ console_lock();
+ fb_set_suspend(bochs->fb.helper.fbdev, 1);
+ console_unlock();
+ }
+
+ return 0;
+}
+
+static int bochs_pm_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct bochs_device *bochs = drm_dev->dev_private;
+
+ drm_helper_resume_force_mode(drm_dev);
+
+ if (bochs->fb.initialized) {
+ console_lock();
+ fb_set_suspend(bochs->fb.helper.fbdev, 0);
+ console_unlock();
+ }
+
+ drm_kms_helper_poll_enable(drm_dev);
+ return 0;
+}
+
+static const struct dev_pm_ops bochs_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(bochs_pm_suspend,
+ bochs_pm_resume)
+};
+
/* ---------------------------------------------------------------------- */
/* pci interface */
.id_table = bochs_pci_tbl,
.probe = bochs_pci_probe,
.remove = bochs_pci_remove,
+ .driver.pm = &bochs_pm_ops,
};
/* ---------------------------------------------------------------------- */
int ret;
bochs->fb.helper.funcs = &bochs_fb_helper_funcs;
- spin_lock_init(&bochs->fb.dirty_lock);
ret = drm_fb_helper_init(bochs->dev, &bochs->fb.helper,
1, 1);
#include <linux/module.h>
#include <linux/console.h>
#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include "cirrus_drv.h"
drm_put_dev(dev);
}
+static int cirrus_pm_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct cirrus_device *cdev = drm_dev->dev_private;
+
+ drm_kms_helper_poll_disable(drm_dev);
+
+ if (cdev->mode_info.gfbdev) {
+ console_lock();
+ fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 1);
+ console_unlock();
+ }
+
+ return 0;
+}
+
+static int cirrus_pm_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct cirrus_device *cdev = drm_dev->dev_private;
+
+ drm_helper_resume_force_mode(drm_dev);
+
+ if (cdev->mode_info.gfbdev) {
+ console_lock();
+ fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0);
+ console_unlock();
+ }
+
+ drm_kms_helper_poll_enable(drm_dev);
+ return 0;
+}
+
static const struct file_operations cirrus_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
.dumb_destroy = drm_gem_dumb_destroy,
};
+static const struct dev_pm_ops cirrus_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(cirrus_pm_suspend,
+ cirrus_pm_resume)
+};
+
static struct pci_driver cirrus_pci_driver = {
.name = DRIVER_NAME,
.id_table = pciidlist,
.probe = cirrus_pci_probe,
.remove = cirrus_pci_remove,
+ .driver.pm = &cirrus_pm_ops,
};
static int __init cirrus_init(void)
WREG_HDR(hdr);
cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0);
+
+ /* Unblank (needed on S3 resume, vgabios doesn't do it then) */
+ outb(0x20, 0x3c0);
return 0;
}
}
EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
-static bool drm_kms_helper_poll = true;
-module_param_named(poll, drm_kms_helper_poll, bool, 0600);
-
-static void drm_mode_validate_flag(struct drm_connector *connector,
- int flags)
-{
- struct drm_display_mode *mode;
-
- if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
- DRM_MODE_FLAG_3D_MASK))
- return;
-
- list_for_each_entry(mode, &connector->modes, head) {
- if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
- !(flags & DRM_MODE_FLAG_INTERLACE))
- mode->status = MODE_NO_INTERLACE;
- if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
- !(flags & DRM_MODE_FLAG_DBLSCAN))
- mode->status = MODE_NO_DBLESCAN;
- if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
- !(flags & DRM_MODE_FLAG_3D_MASK))
- mode->status = MODE_NO_STEREO;
- }
-
- return;
-}
-
-/**
- * drm_helper_probe_single_connector_modes - get complete set of display modes
- * @connector: connector to probe
- * @maxX: max width for modes
- * @maxY: max height for modes
- *
- * Based on the helper callbacks implemented by @connector try to detect all
- * valid modes. Modes will first be added to the connector's probed_modes list,
- * then culled (based on validity and the @maxX, @maxY parameters) and put into
- * the normal modes list.
- *
- * Intended to be use as a generic implementation of the ->fill_modes()
- * @connector vfunc for drivers that use the crtc helpers for output mode
- * filtering and detection.
- *
- * Returns:
- * The number of modes found on @connector.
- */
-int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
- uint32_t maxX, uint32_t maxY)
-{
- struct drm_device *dev = connector->dev;
- struct drm_display_mode *mode;
- struct drm_connector_helper_funcs *connector_funcs =
- connector->helper_private;
- int count = 0;
- int mode_flags = 0;
- bool verbose_prune = true;
-
- WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
-
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
- drm_get_connector_name(connector));
- /* set all modes to the unverified state */
- list_for_each_entry(mode, &connector->modes, head)
- mode->status = MODE_UNVERIFIED;
-
- if (connector->force) {
- if (connector->force == DRM_FORCE_ON)
- connector->status = connector_status_connected;
- else
- connector->status = connector_status_disconnected;
- if (connector->funcs->force)
- connector->funcs->force(connector);
- } else {
- connector->status = connector->funcs->detect(connector, true);
- }
-
- /* Re-enable polling in case the global poll config changed. */
- if (drm_kms_helper_poll != dev->mode_config.poll_running)
- drm_kms_helper_poll_enable(dev);
-
- dev->mode_config.poll_running = drm_kms_helper_poll;
-
- if (connector->status == connector_status_disconnected) {
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
- connector->base.id, drm_get_connector_name(connector));
- drm_mode_connector_update_edid_property(connector, NULL);
- verbose_prune = false;
- goto prune;
- }
-
-#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
- count = drm_load_edid_firmware(connector);
- if (count == 0)
-#endif
- count = (*connector_funcs->get_modes)(connector);
-
- if (count == 0 && connector->status == connector_status_connected)
- count = drm_add_modes_noedid(connector, 1024, 768);
- if (count == 0)
- goto prune;
-
- drm_mode_connector_list_update(connector);
-
- if (maxX && maxY)
- drm_mode_validate_size(dev, &connector->modes, maxX, maxY);
-
- if (connector->interlace_allowed)
- mode_flags |= DRM_MODE_FLAG_INTERLACE;
- if (connector->doublescan_allowed)
- mode_flags |= DRM_MODE_FLAG_DBLSCAN;
- if (connector->stereo_allowed)
- mode_flags |= DRM_MODE_FLAG_3D_MASK;
- drm_mode_validate_flag(connector, mode_flags);
-
- list_for_each_entry(mode, &connector->modes, head) {
- if (mode->status == MODE_OK)
- mode->status = connector_funcs->mode_valid(connector,
- mode);
- }
-
-prune:
- drm_mode_prune_invalid(dev, &connector->modes, verbose_prune);
-
- if (list_empty(&connector->modes))
- return 0;
-
- list_for_each_entry(mode, &connector->modes, head)
- mode->vrefresh = drm_mode_vrefresh(mode);
-
- drm_mode_sort(&connector->modes);
-
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
- drm_get_connector_name(connector));
- list_for_each_entry(mode, &connector->modes, head) {
- drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
- drm_mode_debug_printmodeline(mode);
- }
-
- return count;
-}
-EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
-
/**
* drm_helper_encoder_in_use - check if a given encoder is in use
* @encoder: encoder to check
drm_modeset_unlock_all(dev);
}
EXPORT_SYMBOL(drm_helper_resume_force_mode);
-
-/**
- * drm_kms_helper_hotplug_event - fire off KMS hotplug events
- * @dev: drm_device whose connector state changed
- *
- * This function fires off the uevent for userspace and also calls the
- * output_poll_changed function, which is most commonly used to inform the fbdev
- * emulation code and allow it to update the fbcon output configuration.
- *
- * Drivers should call this from their hotplug handling code when a change is
- * detected. Note that this function does not do any output detection of its
- * own, like drm_helper_hpd_irq_event() does - this is assumed to be done by the
- * driver already.
- *
- * This function must be called from process context with no mode
- * setting locks held.
- */
-void drm_kms_helper_hotplug_event(struct drm_device *dev)
-{
- /* send a uevent + call fbdev */
- drm_sysfs_hotplug_event(dev);
- if (dev->mode_config.funcs->output_poll_changed)
- dev->mode_config.funcs->output_poll_changed(dev);
-}
-EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
-
-#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
-static void output_poll_execute(struct work_struct *work)
-{
- struct delayed_work *delayed_work = to_delayed_work(work);
- struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
- struct drm_connector *connector;
- enum drm_connector_status old_status;
- bool repoll = false, changed = false;
-
- if (!drm_kms_helper_poll)
- return;
-
- mutex_lock(&dev->mode_config.mutex);
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-
- /* Ignore forced connectors. */
- if (connector->force)
- continue;
-
- /* Ignore HPD capable connectors and connectors where we don't
- * want any hotplug detection at all for polling. */
- if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
- continue;
-
- repoll = true;
-
- old_status = connector->status;
- /* if we are connected and don't want to poll for disconnect
- skip it */
- if (old_status == connector_status_connected &&
- !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
- continue;
-
- connector->status = connector->funcs->detect(connector, false);
- if (old_status != connector->status) {
- const char *old, *new;
-
- old = drm_get_connector_status_name(old_status);
- new = drm_get_connector_status_name(connector->status);
-
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
- "status updated from %s to %s\n",
- connector->base.id,
- drm_get_connector_name(connector),
- old, new);
-
- changed = true;
- }
- }
-
- mutex_unlock(&dev->mode_config.mutex);
-
- if (changed)
- drm_kms_helper_hotplug_event(dev);
-
- if (repoll)
- schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
-}
-
-/**
- * drm_kms_helper_poll_disable - disable output polling
- * @dev: drm_device
- *
- * This function disables the output polling work.
- *
- * Drivers can call this helper from their device suspend implementation. It is
- * not an error to call this even when output polling isn't enabled or arlready
- * disabled.
- */
-void drm_kms_helper_poll_disable(struct drm_device *dev)
-{
- if (!dev->mode_config.poll_enabled)
- return;
- cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
-}
-EXPORT_SYMBOL(drm_kms_helper_poll_disable);
-
-/**
- * drm_kms_helper_poll_enable - re-enable output polling.
- * @dev: drm_device
- *
- * This function re-enables the output polling work.
- *
- * Drivers can call this helper from their device resume implementation. It is
- * an error to call this when the output polling support has not yet been set
- * up.
- */
-void drm_kms_helper_poll_enable(struct drm_device *dev)
-{
- bool poll = false;
- struct drm_connector *connector;
-
- if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
- return;
-
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
- DRM_CONNECTOR_POLL_DISCONNECT))
- poll = true;
- }
-
- if (poll)
- schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
-}
-EXPORT_SYMBOL(drm_kms_helper_poll_enable);
-
-/**
- * drm_kms_helper_poll_init - initialize and enable output polling
- * @dev: drm_device
- *
- * This function intializes and then also enables output polling support for
- * @dev. Drivers which do not have reliable hotplug support in hardware can use
- * this helper infrastructure to regularly poll such connectors for changes in
- * their connection state.
- *
- * Drivers can control which connectors are polled by setting the
- * DRM_CONNECTOR_POLL_CONNECT and DRM_CONNECTOR_POLL_DISCONNECT flags. On
- * connectors where probing live outputs can result in visual distortion drivers
- * should not set the DRM_CONNECTOR_POLL_DISCONNECT flag to avoid this.
- * Connectors which have no flag or only DRM_CONNECTOR_POLL_HPD set are
- * completely ignored by the polling logic.
- *
- * Note that a connector can be both polled and probed from the hotplug handler,
- * in case the hotplug interrupt is known to be unreliable.
- */
-void drm_kms_helper_poll_init(struct drm_device *dev)
-{
- INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute);
- dev->mode_config.poll_enabled = true;
-
- drm_kms_helper_poll_enable(dev);
-}
-EXPORT_SYMBOL(drm_kms_helper_poll_init);
-
-/**
- * drm_kms_helper_poll_fini - disable output polling and clean it up
- * @dev: drm_device
- */
-void drm_kms_helper_poll_fini(struct drm_device *dev)
-{
- drm_kms_helper_poll_disable(dev);
-}
-EXPORT_SYMBOL(drm_kms_helper_poll_fini);
-
-/**
- * drm_helper_hpd_irq_event - hotplug processing
- * @dev: drm_device
- *
- * Drivers can use this helper function to run a detect cycle on all connectors
- * which have the DRM_CONNECTOR_POLL_HPD flag set in their &polled member. All
- * other connectors are ignored, which is useful to avoid reprobing fixed
- * panels.
- *
- * This helper function is useful for drivers which can't or don't track hotplug
- * interrupts for each connector.
- *
- * Drivers which support hotplug interrupts for each connector individually and
- * which have a more fine-grained detect logic should bypass this code and
- * directly call drm_kms_helper_hotplug_event() in case the connector state
- * changed.
- *
- * This function must be called from process context with no mode
- * setting locks held.
- *
- * Note that a connector can be both polled and probed from the hotplug handler,
- * in case the hotplug interrupt is known to be unreliable.
- */
-bool drm_helper_hpd_irq_event(struct drm_device *dev)
-{
- struct drm_connector *connector;
- enum drm_connector_status old_status;
- bool changed = false;
-
- if (!dev->mode_config.poll_enabled)
- return false;
-
- mutex_lock(&dev->mode_config.mutex);
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-
- /* Only handle HPD capable connectors. */
- if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
- continue;
-
- old_status = connector->status;
-
- connector->status = connector->funcs->detect(connector, false);
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
- connector->base.id,
- drm_get_connector_name(connector),
- drm_get_connector_status_name(old_status),
- drm_get_connector_status_name(connector->status));
- if (old_status != connector->status)
- changed = true;
- }
-
- mutex_unlock(&dev->mode_config.mutex);
-
- if (changed)
- drm_kms_helper_hotplug_event(dev);
-
- return changed;
-}
-EXPORT_SYMBOL(drm_helper_hpd_irq_event);
/*
* Transfer a single I2C-over-AUX message and handle various error conditions,
- * retrying the transaction as appropriate.
+ * retrying the transaction as appropriate. It is assumed that the
+ * aux->transfer function does not modify anything in the msg other than the
+ * reply field.
*/
static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
{
{
struct drm_dp_aux *aux = adapter->algo_data;
unsigned int i, j;
+ struct drm_dp_aux_msg msg;
+ int err = 0;
- for (i = 0; i < num; i++) {
- struct drm_dp_aux_msg msg;
- int err;
+ memset(&msg, 0, sizeof(msg));
+ for (i = 0; i < num; i++) {
+ msg.address = msgs[i].addr;
+ msg.request = (msgs[i].flags & I2C_M_RD) ?
+ DP_AUX_I2C_READ :
+ DP_AUX_I2C_WRITE;
+ msg.request |= DP_AUX_I2C_MOT;
+ /* Send a bare address packet to start the transaction.
+ * Zero sized messages specify an address only (bare
+ * address) transaction.
+ */
+ msg.buffer = NULL;
+ msg.size = 0;
+ err = drm_dp_i2c_do_msg(aux, &msg);
+ if (err < 0)
+ break;
/*
* Many hardware implementations support FIFOs larger than a
* single byte, but it has been empirically determined that
* transferred byte-by-byte.
*/
for (j = 0; j < msgs[i].len; j++) {
- memset(&msg, 0, sizeof(msg));
- msg.address = msgs[i].addr;
-
- msg.request = (msgs[i].flags & I2C_M_RD) ?
- DP_AUX_I2C_READ :
- DP_AUX_I2C_WRITE;
-
- /*
- * All messages except the last one are middle-of-
- * transfer messages.
- */
- if ((i < num - 1) || (j < msgs[i].len - 1))
- msg.request |= DP_AUX_I2C_MOT;
-
msg.buffer = msgs[i].buf + j;
msg.size = 1;
err = drm_dp_i2c_do_msg(aux, &msg);
if (err < 0)
- return err;
+ break;
}
+ if (err < 0)
+ break;
}
+ if (err >= 0)
+ err = num;
+ /* Send a bare address packet to close out the transaction.
+ * Zero sized messages specify an address only (bare
+ * address) transaction.
+ */
+ msg.request &= ~DP_AUX_I2C_MOT;
+ msg.buffer = NULL;
+ msg.size = 0;
+ (void)drm_dp_i2c_do_msg(aux, &msg);
- return num;
+ return err;
}
static const struct i2c_algorithm drm_dp_i2c_algo = {
return 0;
}
- WARN(1, "no hole found for node 0x%lx + 0x%lx\n",
- node->start, node->size);
return -ENOSPC;
}
EXPORT_SYMBOL(drm_mm_reserve_node);
*
* Provides a default plane disable handler for primary planes. This is handler
* is called in response to a userspace SetPlane operation on the plane with a
- * NULL framebuffer parameter. We call the driver's modeset handler with a NULL
- * framebuffer to disable the CRTC if no other planes are currently enabled.
- * If other planes are still enabled on the same CRTC, we return -EBUSY.
+ * NULL framebuffer parameter. It unconditionally fails the disable call with
+ * -EINVAL the only way to disable the primary plane without driver support is
+ * to disable the entier CRTC. Which does not match the plane ->disable hook.
*
* Note that some hardware may be able to disable the primary plane without
* disabling the whole CRTC. Drivers for such hardware should provide their
* disabled primary plane).
*
* RETURNS:
- * Zero on success, error code on failure
+ * Unconditionally returns -EINVAL.
*/
int drm_primary_helper_disable(struct drm_plane *plane)
{
- struct drm_plane *p;
- struct drm_mode_set set = {
- .crtc = plane->crtc,
- .fb = NULL,
- };
-
- if (plane->crtc == NULL || plane->fb == NULL)
- /* Already disabled */
- return 0;
-
- list_for_each_entry(p, &plane->dev->mode_config.plane_list, head)
- if (p != plane && p->fb) {
- DRM_DEBUG_KMS("Cannot disable primary plane while other planes are still active on CRTC.\n");
- return -EBUSY;
- }
-
- /*
- * N.B. We call set_config() directly here rather than
- * drm_mode_set_config_internal() since drm_mode_setplane() already
- * handles the basic refcounting and we don't need the special
- * cross-CRTC refcounting (no chance of stealing connectors from
- * other CRTC's with this update).
- */
- return plane->crtc->funcs->set_config(&set);
+ return -EINVAL;
}
EXPORT_SYMBOL(drm_primary_helper_disable);
--- /dev/null
+/*
+ * Copyright (c) 2006-2008 Intel Corporation
+ * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
+ *
+ * DRM core CRTC related functions
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Keith Packard
+ * Eric Anholt <eric@anholt.net>
+ * Dave Airlie <airlied@linux.ie>
+ * Jesse Barnes <jesse.barnes@intel.com>
+ */
+
+#include <linux/export.h>
+#include <linux/moduleparam.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_edid.h>
+
+/**
+ * DOC: output probing helper overview
+ *
+ * This library provides some helper code for output probing. It provides an
+ * implementation of the core connector->fill_modes interface with
+ * drm_helper_probe_single_connector_modes.
+ *
+ * It also provides support for polling connectors with a work item and for
+ * generic hotplug interrupt handling where the driver doesn't or cannot keep
+ * track of a per-connector hpd interrupt.
+ *
+ * This helper library can be used independently of the modeset helper library.
+ * Drivers can also overwrite different parts e.g. use their own hotplug
+ * handling code to avoid probing unrelated outputs.
+ */
+
+static bool drm_kms_helper_poll = true;
+module_param_named(poll, drm_kms_helper_poll, bool, 0600);
+
+static void drm_mode_validate_flag(struct drm_connector *connector,
+ int flags)
+{
+ struct drm_display_mode *mode;
+
+ if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
+ DRM_MODE_FLAG_3D_MASK))
+ return;
+
+ list_for_each_entry(mode, &connector->modes, head) {
+ if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
+ !(flags & DRM_MODE_FLAG_INTERLACE))
+ mode->status = MODE_NO_INTERLACE;
+ if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
+ !(flags & DRM_MODE_FLAG_DBLSCAN))
+ mode->status = MODE_NO_DBLESCAN;
+ if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
+ !(flags & DRM_MODE_FLAG_3D_MASK))
+ mode->status = MODE_NO_STEREO;
+ }
+
+ return;
+}
+
+/**
+ * drm_helper_probe_single_connector_modes - get complete set of display modes
+ * @connector: connector to probe
+ * @maxX: max width for modes
+ * @maxY: max height for modes
+ *
+ * Based on the helper callbacks implemented by @connector try to detect all
+ * valid modes. Modes will first be added to the connector's probed_modes list,
+ * then culled (based on validity and the @maxX, @maxY parameters) and put into
+ * the normal modes list.
+ *
+ * Intended to be use as a generic implementation of the ->fill_modes()
+ * @connector vfunc for drivers that use the crtc helpers for output mode
+ * filtering and detection.
+ *
+ * Returns:
+ * The number of modes found on @connector.
+ */
+int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
+ uint32_t maxX, uint32_t maxY)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_display_mode *mode;
+ struct drm_connector_helper_funcs *connector_funcs =
+ connector->helper_private;
+ int count = 0;
+ int mode_flags = 0;
+ bool verbose_prune = true;
+
+ WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
+
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
+ drm_get_connector_name(connector));
+ /* set all modes to the unverified state */
+ list_for_each_entry(mode, &connector->modes, head)
+ mode->status = MODE_UNVERIFIED;
+
+ if (connector->force) {
+ if (connector->force == DRM_FORCE_ON)
+ connector->status = connector_status_connected;
+ else
+ connector->status = connector_status_disconnected;
+ if (connector->funcs->force)
+ connector->funcs->force(connector);
+ } else {
+ connector->status = connector->funcs->detect(connector, true);
+ }
+
+ /* Re-enable polling in case the global poll config changed. */
+ if (drm_kms_helper_poll != dev->mode_config.poll_running)
+ drm_kms_helper_poll_enable(dev);
+
+ dev->mode_config.poll_running = drm_kms_helper_poll;
+
+ if (connector->status == connector_status_disconnected) {
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
+ connector->base.id, drm_get_connector_name(connector));
+ drm_mode_connector_update_edid_property(connector, NULL);
+ verbose_prune = false;
+ goto prune;
+ }
+
+#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
+ count = drm_load_edid_firmware(connector);
+ if (count == 0)
+#endif
+ count = (*connector_funcs->get_modes)(connector);
+
+ if (count == 0 && connector->status == connector_status_connected)
+ count = drm_add_modes_noedid(connector, 1024, 768);
+ if (count == 0)
+ goto prune;
+
+ drm_mode_connector_list_update(connector);
+
+ if (maxX && maxY)
+ drm_mode_validate_size(dev, &connector->modes, maxX, maxY);
+
+ if (connector->interlace_allowed)
+ mode_flags |= DRM_MODE_FLAG_INTERLACE;
+ if (connector->doublescan_allowed)
+ mode_flags |= DRM_MODE_FLAG_DBLSCAN;
+ if (connector->stereo_allowed)
+ mode_flags |= DRM_MODE_FLAG_3D_MASK;
+ drm_mode_validate_flag(connector, mode_flags);
+
+ list_for_each_entry(mode, &connector->modes, head) {
+ if (mode->status == MODE_OK)
+ mode->status = connector_funcs->mode_valid(connector,
+ mode);
+ }
+
+prune:
+ drm_mode_prune_invalid(dev, &connector->modes, verbose_prune);
+
+ if (list_empty(&connector->modes))
+ return 0;
+
+ list_for_each_entry(mode, &connector->modes, head)
+ mode->vrefresh = drm_mode_vrefresh(mode);
+
+ drm_mode_sort(&connector->modes);
+
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
+ drm_get_connector_name(connector));
+ list_for_each_entry(mode, &connector->modes, head) {
+ drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+ drm_mode_debug_printmodeline(mode);
+ }
+
+ return count;
+}
+EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
+
+/**
+ * drm_kms_helper_hotplug_event - fire off KMS hotplug events
+ * @dev: drm_device whose connector state changed
+ *
+ * This function fires off the uevent for userspace and also calls the
+ * output_poll_changed function, which is most commonly used to inform the fbdev
+ * emulation code and allow it to update the fbcon output configuration.
+ *
+ * Drivers should call this from their hotplug handling code when a change is
+ * detected. Note that this function does not do any output detection of its
+ * own, like drm_helper_hpd_irq_event() does - this is assumed to be done by the
+ * driver already.
+ *
+ * This function must be called from process context with no mode
+ * setting locks held.
+ */
+void drm_kms_helper_hotplug_event(struct drm_device *dev)
+{
+ /* send a uevent + call fbdev */
+ drm_sysfs_hotplug_event(dev);
+ if (dev->mode_config.funcs->output_poll_changed)
+ dev->mode_config.funcs->output_poll_changed(dev);
+}
+EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
+
+#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
+static void output_poll_execute(struct work_struct *work)
+{
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
+ struct drm_connector *connector;
+ enum drm_connector_status old_status;
+ bool repoll = false, changed = false;
+
+ if (!drm_kms_helper_poll)
+ return;
+
+ mutex_lock(&dev->mode_config.mutex);
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+
+ /* Ignore forced connectors. */
+ if (connector->force)
+ continue;
+
+ /* Ignore HPD capable connectors and connectors where we don't
+ * want any hotplug detection at all for polling. */
+ if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
+ continue;
+
+ repoll = true;
+
+ old_status = connector->status;
+ /* if we are connected and don't want to poll for disconnect
+ skip it */
+ if (old_status == connector_status_connected &&
+ !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
+ continue;
+
+ connector->status = connector->funcs->detect(connector, false);
+ if (old_status != connector->status) {
+ const char *old, *new;
+
+ old = drm_get_connector_status_name(old_status);
+ new = drm_get_connector_status_name(connector->status);
+
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
+ "status updated from %s to %s\n",
+ connector->base.id,
+ drm_get_connector_name(connector),
+ old, new);
+
+ changed = true;
+ }
+ }
+
+ mutex_unlock(&dev->mode_config.mutex);
+
+ if (changed)
+ drm_kms_helper_hotplug_event(dev);
+
+ if (repoll)
+ schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
+}
+
+/**
+ * drm_kms_helper_poll_disable - disable output polling
+ * @dev: drm_device
+ *
+ * This function disables the output polling work.
+ *
+ * Drivers can call this helper from their device suspend implementation. It is
+ * not an error to call this even when output polling isn't enabled or arlready
+ * disabled.
+ */
+void drm_kms_helper_poll_disable(struct drm_device *dev)
+{
+ if (!dev->mode_config.poll_enabled)
+ return;
+ cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_disable);
+
+/**
+ * drm_kms_helper_poll_enable - re-enable output polling.
+ * @dev: drm_device
+ *
+ * This function re-enables the output polling work.
+ *
+ * Drivers can call this helper from their device resume implementation. It is
+ * an error to call this when the output polling support has not yet been set
+ * up.
+ */
+void drm_kms_helper_poll_enable(struct drm_device *dev)
+{
+ bool poll = false;
+ struct drm_connector *connector;
+
+ if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
+ return;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
+ DRM_CONNECTOR_POLL_DISCONNECT))
+ poll = true;
+ }
+
+ if (poll)
+ schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_enable);
+
+/**
+ * drm_kms_helper_poll_init - initialize and enable output polling
+ * @dev: drm_device
+ *
+ * This function intializes and then also enables output polling support for
+ * @dev. Drivers which do not have reliable hotplug support in hardware can use
+ * this helper infrastructure to regularly poll such connectors for changes in
+ * their connection state.
+ *
+ * Drivers can control which connectors are polled by setting the
+ * DRM_CONNECTOR_POLL_CONNECT and DRM_CONNECTOR_POLL_DISCONNECT flags. On
+ * connectors where probing live outputs can result in visual distortion drivers
+ * should not set the DRM_CONNECTOR_POLL_DISCONNECT flag to avoid this.
+ * Connectors which have no flag or only DRM_CONNECTOR_POLL_HPD set are
+ * completely ignored by the polling logic.
+ *
+ * Note that a connector can be both polled and probed from the hotplug handler,
+ * in case the hotplug interrupt is known to be unreliable.
+ */
+void drm_kms_helper_poll_init(struct drm_device *dev)
+{
+ INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute);
+ dev->mode_config.poll_enabled = true;
+
+ drm_kms_helper_poll_enable(dev);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_init);
+
+/**
+ * drm_kms_helper_poll_fini - disable output polling and clean it up
+ * @dev: drm_device
+ */
+void drm_kms_helper_poll_fini(struct drm_device *dev)
+{
+ drm_kms_helper_poll_disable(dev);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_fini);
+
+/**
+ * drm_helper_hpd_irq_event - hotplug processing
+ * @dev: drm_device
+ *
+ * Drivers can use this helper function to run a detect cycle on all connectors
+ * which have the DRM_CONNECTOR_POLL_HPD flag set in their &polled member. All
+ * other connectors are ignored, which is useful to avoid reprobing fixed
+ * panels.
+ *
+ * This helper function is useful for drivers which can't or don't track hotplug
+ * interrupts for each connector.
+ *
+ * Drivers which support hotplug interrupts for each connector individually and
+ * which have a more fine-grained detect logic should bypass this code and
+ * directly call drm_kms_helper_hotplug_event() in case the connector state
+ * changed.
+ *
+ * This function must be called from process context with no mode
+ * setting locks held.
+ *
+ * Note that a connector can be both polled and probed from the hotplug handler,
+ * in case the hotplug interrupt is known to be unreliable.
+ */
+bool drm_helper_hpd_irq_event(struct drm_device *dev)
+{
+ struct drm_connector *connector;
+ enum drm_connector_status old_status;
+ bool changed = false;
+
+ if (!dev->mode_config.poll_enabled)
+ return false;
+
+ mutex_lock(&dev->mode_config.mutex);
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+
+ /* Only handle HPD capable connectors. */
+ if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
+ continue;
+
+ old_status = connector->status;
+
+ connector->status = connector->funcs->detect(connector, false);
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
+ connector->base.id,
+ drm_get_connector_name(connector),
+ drm_get_connector_status_name(old_status),
+ drm_get_connector_status_name(connector->status));
+ if (old_status != connector->status)
+ changed = true;
+ }
+
+ mutex_unlock(&dev->mode_config.mutex);
+
+ if (changed)
+ drm_kms_helper_hotplug_event(dev);
+
+ return changed;
+}
+EXPORT_SYMBOL(drm_helper_hpd_irq_event);
struct {
u16 pwm_freq_hz;
+ bool present;
bool active_low_pwm;
} backlight;
int i915_gem_context_enable(struct drm_i915_private *dev_priv);
void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
int i915_switch_context(struct intel_ring_buffer *ring,
- struct drm_file *file, struct i915_hw_context *to);
+ struct i915_hw_context *to);
struct i915_hw_context *
i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
void i915_gem_context_free(struct kref *ctx_ref);
static inline void i915_gem_context_reference(struct i915_hw_context *ctx)
{
- if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev))
- kref_get(&ctx->ref);
+ kref_get(&ctx->ref);
}
static inline void i915_gem_context_unreference(struct i915_hw_context *ctx)
{
- if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev))
- kref_put(&ctx->ref, i915_gem_context_free);
+ kref_put(&ctx->ref, i915_gem_context_free);
}
static inline bool i915_gem_context_is_default(const struct i915_hw_context *c)
/* Flush everything onto the inactive list. */
for_each_ring(ring, dev_priv, i) {
- ret = i915_switch_context(ring, NULL, ring->default_context);
+ ret = i915_switch_context(ring, ring->default_context);
if (ret)
return ret;
#define GEN6_CONTEXT_ALIGN (64<<10)
#define GEN7_CONTEXT_ALIGN 4096
-static int do_switch(struct intel_ring_buffer *ring,
- struct i915_hw_context *to);
-
static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt)
{
struct drm_device *dev = ppgtt->base.dev;
typeof(*ctx), ref);
struct i915_hw_ppgtt *ppgtt = NULL;
- /* We refcount even the aliasing PPGTT to keep the code symmetric */
- if (USES_PPGTT(ctx->obj->base.dev))
- ppgtt = ctx_to_ppgtt(ctx);
+ if (ctx->obj) {
+ /* We refcount even the aliasing PPGTT to keep the code symmetric */
+ if (USES_PPGTT(ctx->obj->base.dev))
+ ppgtt = ctx_to_ppgtt(ctx);
- /* XXX: Free up the object before tearing down the address space, in
- * case we're bound in the PPGTT */
- drm_gem_object_unreference(&ctx->obj->base);
+ /* XXX: Free up the object before tearing down the address space, in
+ * case we're bound in the PPGTT */
+ drm_gem_object_unreference(&ctx->obj->base);
+ }
if (ppgtt)
kref_put(&ppgtt->ref, ppgtt_release);
return ERR_PTR(-ENOMEM);
kref_init(&ctx->ref);
- ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
- INIT_LIST_HEAD(&ctx->link);
- if (ctx->obj == NULL) {
- kfree(ctx);
- DRM_DEBUG_DRIVER("Context object allocated failed\n");
- return ERR_PTR(-ENOMEM);
- }
+ list_add_tail(&ctx->link, &dev_priv->context_list);
- if (INTEL_INFO(dev)->gen >= 7) {
- ret = i915_gem_object_set_cache_level(ctx->obj,
- I915_CACHE_L3_LLC);
- /* Failure shouldn't ever happen this early */
- if (WARN_ON(ret))
+ if (dev_priv->hw_context_size) {
+ ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
+ if (ctx->obj == NULL) {
+ ret = -ENOMEM;
goto err_out;
- }
+ }
- list_add_tail(&ctx->link, &dev_priv->context_list);
+ if (INTEL_INFO(dev)->gen >= 7) {
+ ret = i915_gem_object_set_cache_level(ctx->obj,
+ I915_CACHE_L3_LLC);
+ /* Failure shouldn't ever happen this early */
+ if (WARN_ON(ret))
+ goto err_out;
+ }
+ }
/* Default context will never have a file_priv */
- if (file_priv == NULL)
- return ctx;
-
- ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID, 0,
- GFP_KERNEL);
- if (ret < 0)
- goto err_out;
+ if (file_priv != NULL) {
+ ret = idr_alloc(&file_priv->context_idr, ctx,
+ DEFAULT_CONTEXT_ID, 0, GFP_KERNEL);
+ if (ret < 0)
+ goto err_out;
+ } else
+ ret = DEFAULT_CONTEXT_ID;
ctx->file_priv = file_priv;
ctx->id = ret;
if (IS_ERR(ctx))
return ctx;
- if (is_global_default_ctx) {
+ if (is_global_default_ctx && ctx->obj) {
/* We may need to do things with the shrinker which
* require us to immediately switch back to the default
* context. This can cause a problem as pinning the
return ctx;
err_unpin:
- if (is_global_default_ctx)
+ if (is_global_default_ctx && ctx->obj)
i915_gem_object_ggtt_unpin(ctx->obj);
err_destroy:
i915_gem_context_unreference(ctx);
void i915_gem_context_reset(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_ring_buffer *ring;
int i;
- if (!HAS_HW_CONTEXTS(dev))
- return;
-
/* Prevent the hardware from restoring the last context (which hung) on
* the next switch */
for (i = 0; i < I915_NUM_RINGS; i++) {
- struct i915_hw_context *dctx;
- if (!(INTEL_INFO(dev)->ring_mask & (1<<i)))
- continue;
+ struct intel_ring_buffer *ring = &dev_priv->ring[i];
+ struct i915_hw_context *dctx = ring->default_context;
/* Do a fake switch to the default context */
- ring = &dev_priv->ring[i];
- dctx = ring->default_context;
- if (WARN_ON(!dctx))
+ if (ring->last_context == dctx)
continue;
if (!ring->last_context)
continue;
- if (ring->last_context == dctx)
- continue;
-
- if (i == RCS) {
+ if (dctx->obj && i == RCS) {
WARN_ON(i915_gem_obj_ggtt_pin(dctx->obj,
get_context_alignment(dev), 0));
/* Fake a finish/inactive */
int i915_gem_context_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_ring_buffer *ring;
+ struct i915_hw_context *ctx;
int i;
- if (!HAS_HW_CONTEXTS(dev))
- return 0;
-
/* Init should only be called once per module load. Eventually the
* restriction on the context_disabled check can be loosened. */
if (WARN_ON(dev_priv->ring[RCS].default_context))
return 0;
- dev_priv->hw_context_size = round_up(get_context_size(dev), 4096);
-
- if (dev_priv->hw_context_size > (1<<20)) {
- DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size\n");
- return -E2BIG;
+ if (HAS_HW_CONTEXTS(dev)) {
+ dev_priv->hw_context_size = round_up(get_context_size(dev), 4096);
+ if (dev_priv->hw_context_size > (1<<20)) {
+ DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size %d\n",
+ dev_priv->hw_context_size);
+ dev_priv->hw_context_size = 0;
+ }
}
- dev_priv->ring[RCS].default_context =
- i915_gem_create_context(dev, NULL, USES_PPGTT(dev));
-
- if (IS_ERR_OR_NULL(dev_priv->ring[RCS].default_context)) {
- DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed %ld\n",
- PTR_ERR(dev_priv->ring[RCS].default_context));
- return PTR_ERR(dev_priv->ring[RCS].default_context);
+ ctx = i915_gem_create_context(dev, NULL, USES_PPGTT(dev));
+ if (IS_ERR(ctx)) {
+ DRM_ERROR("Failed to create default global context (error %ld)\n",
+ PTR_ERR(ctx));
+ return PTR_ERR(ctx);
}
- for (i = RCS + 1; i < I915_NUM_RINGS; i++) {
- if (!(INTEL_INFO(dev)->ring_mask & (1<<i)))
- continue;
-
- ring = &dev_priv->ring[i];
+ /* NB: RCS will hold a ref for all rings */
+ for (i = 0; i < I915_NUM_RINGS; i++)
+ dev_priv->ring[i].default_context = ctx;
- /* NB: RCS will hold a ref for all rings */
- ring->default_context = dev_priv->ring[RCS].default_context;
- }
-
- DRM_DEBUG_DRIVER("HW context support initialized\n");
+ DRM_DEBUG_DRIVER("%s context support initialized\n", dev_priv->hw_context_size ? "HW" : "fake");
return 0;
}
struct i915_hw_context *dctx = dev_priv->ring[RCS].default_context;
int i;
- if (!HAS_HW_CONTEXTS(dev))
- return;
-
- /* The only known way to stop the gpu from accessing the hw context is
- * to reset it. Do this as the very last operation to avoid confusing
- * other code, leading to spurious errors. */
- intel_gpu_reset(dev);
-
- /* When default context is created and switched to, base object refcount
- * will be 2 (+1 from object creation and +1 from do_switch()).
- * i915_gem_context_fini() will be called after gpu_idle() has switched
- * to default context. So we need to unreference the base object once
- * to offset the do_switch part, so that i915_gem_context_unreference()
- * can then free the base object correctly. */
- WARN_ON(!dev_priv->ring[RCS].last_context);
- if (dev_priv->ring[RCS].last_context == dctx) {
- /* Fake switch to NULL context */
- WARN_ON(dctx->obj->active);
- i915_gem_object_ggtt_unpin(dctx->obj);
- i915_gem_context_unreference(dctx);
- dev_priv->ring[RCS].last_context = NULL;
+ if (dctx->obj) {
+ /* The only known way to stop the gpu from accessing the hw context is
+ * to reset it. Do this as the very last operation to avoid confusing
+ * other code, leading to spurious errors. */
+ intel_gpu_reset(dev);
+
+ /* When default context is created and switched to, base object refcount
+ * will be 2 (+1 from object creation and +1 from do_switch()).
+ * i915_gem_context_fini() will be called after gpu_idle() has switched
+ * to default context. So we need to unreference the base object once
+ * to offset the do_switch part, so that i915_gem_context_unreference()
+ * can then free the base object correctly. */
+ WARN_ON(!dev_priv->ring[RCS].last_context);
+ if (dev_priv->ring[RCS].last_context == dctx) {
+ /* Fake switch to NULL context */
+ WARN_ON(dctx->obj->active);
+ i915_gem_object_ggtt_unpin(dctx->obj);
+ i915_gem_context_unreference(dctx);
+ dev_priv->ring[RCS].last_context = NULL;
+ }
}
for (i = 0; i < I915_NUM_RINGS; i++) {
struct intel_ring_buffer *ring = &dev_priv->ring[i];
- if (!(INTEL_INFO(dev)->ring_mask & (1<<i)))
- continue;
if (ring->last_context)
i915_gem_context_unreference(ring->last_context);
i915_gem_object_ggtt_unpin(dctx->obj);
i915_gem_context_unreference(dctx);
- dev_priv->mm.aliasing_ppgtt = NULL;
}
int i915_gem_context_enable(struct drm_i915_private *dev_priv)
struct intel_ring_buffer *ring;
int ret, i;
- if (!HAS_HW_CONTEXTS(dev_priv->dev))
- return 0;
-
/* This is the only place the aliasing PPGTT gets enabled, which means
* it has to happen before we bail on reset */
if (dev_priv->mm.aliasing_ppgtt) {
BUG_ON(!dev_priv->ring[RCS].default_context);
for_each_ring(ring, dev_priv, i) {
- ret = do_switch(ring, ring->default_context);
+ ret = i915_switch_context(ring, ring->default_context);
if (ret)
return ret;
}
int i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
{
struct drm_i915_file_private *file_priv = file->driver_priv;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (!HAS_HW_CONTEXTS(dev)) {
- /* Cheat for hang stats */
- file_priv->private_default_ctx =
- kzalloc(sizeof(struct i915_hw_context), GFP_KERNEL);
-
- if (file_priv->private_default_ctx == NULL)
- return -ENOMEM;
-
- file_priv->private_default_ctx->vm = &dev_priv->gtt.base;
- return 0;
- }
idr_init(&file_priv->context_idr);
{
struct drm_i915_file_private *file_priv = file->driver_priv;
- if (!HAS_HW_CONTEXTS(dev)) {
- kfree(file_priv->private_default_ctx);
- return;
- }
-
idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
- i915_gem_context_unreference(file_priv->private_default_ctx);
idr_destroy(&file_priv->context_idr);
+
+ i915_gem_context_unreference(file_priv->private_default_ctx);
}
struct i915_hw_context *
{
struct i915_hw_context *ctx;
- if (!HAS_HW_CONTEXTS(file_priv->dev_priv->dev))
- return file_priv->private_default_ctx;
-
ctx = (struct i915_hw_context *)idr_find(&file_priv->context_idr, id);
if (!ctx)
return ERR_PTR(-ENOENT);
/**
* i915_switch_context() - perform a GPU context switch.
* @ring: ring for which we'll execute the context switch
- * @file_priv: file_priv associated with the context, may be NULL
* @to: the context to switch to
*
* The context life cycle is simple. The context refcount is incremented and
* object while letting the normal object tracking destroy the backing BO.
*/
int i915_switch_context(struct intel_ring_buffer *ring,
- struct drm_file *file,
struct i915_hw_context *to)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
- BUG_ON(file && to == NULL);
-
- /* We have the fake context */
- if (!HAS_HW_CONTEXTS(ring->dev)) {
- ring->last_context = to;
+ if (to->obj == NULL) { /* We have the fake context */
+ if (to != ring->last_context) {
+ i915_gem_context_reference(to);
+ if (ring->last_context)
+ i915_gem_context_unreference(ring->last_context);
+ ring->last_context = to;
+ }
return 0;
}
return do_switch(ring, to);
}
+static bool hw_context_enabled(struct drm_device *dev)
+{
+ return to_i915(dev)->hw_context_size;
+}
+
int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
{
struct i915_hw_context *ctx;
int ret;
- if (!HAS_HW_CONTEXTS(dev))
+ if (!hw_context_enabled(dev))
return -ENODEV;
ret = i915_mutex_lock_interruptible(dev);
if (ret)
goto err;
- ret = i915_switch_context(ring, file, ctx);
+ ret = i915_switch_context(ring, ctx);
if (ret)
goto err;
const struct bdb_lfp_backlight_data *backlight_data;
const struct bdb_lfp_backlight_data_entry *entry;
+ /* Err to enabling backlight if no backlight block. */
+ dev_priv->vbt.backlight.present = true;
+
backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
if (!backlight_data)
return;
entry = &backlight_data->data[panel_type];
+ dev_priv->vbt.backlight.present = entry->type == BDB_BACKLIGHT_TYPE_PWM;
+ if (!dev_priv->vbt.backlight.present) {
+ DRM_DEBUG_KMS("PWM backlight not present in VBT (type %u)\n",
+ entry->type);
+ return;
+ }
+
dev_priv->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
dev_priv->vbt.backlight.active_low_pwm = entry->active_low_pwm;
DRM_DEBUG_KMS("VBT backlight PWM modulation frequency %u Hz, "
struct bdb_lvds_lfp_data_entry data[16];
} __packed;
+#define BDB_BACKLIGHT_TYPE_NONE 0
+#define BDB_BACKLIGHT_TYPE_PWM 2
+
struct bdb_lfp_backlight_data_entry {
u8 type:2;
u8 active_low_pwm:1;
return ret;
}
-#define HEADER_SIZE 4
+#define BARE_ADDRESS_SIZE 3
+#define HEADER_SIZE (BARE_ADDRESS_SIZE + 1)
static ssize_t
intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
{
switch (msg->request & ~DP_AUX_I2C_MOT) {
case DP_AUX_NATIVE_WRITE:
case DP_AUX_I2C_WRITE:
- txsize = HEADER_SIZE + msg->size;
+ txsize = msg->size ? HEADER_SIZE + msg->size : BARE_ADDRESS_SIZE;
rxsize = 1;
if (WARN_ON(txsize > 20))
case DP_AUX_NATIVE_READ:
case DP_AUX_I2C_READ:
- txsize = HEADER_SIZE;
+ txsize = msg->size ? HEADER_SIZE : BARE_ADDRESS_SIZE;
rxsize = msg->size + 1;
if (WARN_ON(rxsize > 20))
unsigned long flags;
int ret;
+ if (!dev_priv->vbt.backlight.present) {
+ DRM_DEBUG_KMS("native backlight control not available per VBT\n");
+ return 0;
+ }
+
/* set level and max in panel struct */
spin_lock_irqsave(&dev_priv->backlight_lock, flags);
ret = dev_priv->display.setup_backlight(intel_connector);
DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
+ if (IS_I915GM(dev) && enabled) {
+ struct intel_framebuffer *fb;
+
+ fb = to_intel_framebuffer(enabled->primary->fb);
+
+ /* self-refresh seems busted with untiled */
+ if (fb->obj->tiling_mode == I915_TILING_NONE)
+ enabled = NULL;
+ }
+
/*
* Overlay gets an aggressive default since video jitter is bad.
*/
return;
}
- addr = (u64)(addr >> 8) << 8;
+ addr = (addr & 0xffffff00) << 8;
if (!addr) {
addr = (u64)nv_rd32(bios, 0x001700) << 16;
addr += 0xf0000;
int pipe;
enum omap_channel channel;
struct omap_overlay_manager_info info;
+ struct drm_encoder *current_encoder;
/*
* Temporary: eventually this will go away, but it is needed
{
}
+static void set_enabled(struct drm_crtc *crtc, bool enable);
+
static int omap_crtc_enable(struct omap_overlay_manager *mgr)
{
+ struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
+
+ dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info);
+ dispc_mgr_set_timings(omap_crtc->channel,
+ &omap_crtc->timings);
+ set_enabled(&omap_crtc->base, true);
+
return 0;
}
static void omap_crtc_disable(struct omap_overlay_manager *mgr)
{
+ struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
+
+ set_enabled(&omap_crtc->base, false);
}
static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
WARN_ON(omap_crtc->apply_irq.registered);
omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
- omap_crtc->plane->funcs->destroy(omap_crtc->plane);
drm_crtc_cleanup(crtc);
kfree(omap_crtc);
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
struct drm_plane *primary = crtc->primary;
struct drm_gem_object *bo;
+ unsigned long flags;
DBG("%d -> %d (event=%p)", primary->fb ? primary->fb->base.id : -1,
fb->base.id, event);
+ spin_lock_irqsave(&dev->event_lock, flags);
+
if (omap_crtc->old_fb) {
+ spin_unlock_irqrestore(&dev->event_lock, flags);
dev_err(dev->dev, "already a pending flip\n");
return -EINVAL;
}
omap_crtc->event = event;
- primary->fb = fb;
+ omap_crtc->old_fb = primary->fb = fb;
+
+ spin_unlock_irqrestore(&dev->event_lock, flags);
/*
* Hold a reference temporarily until the crtc is updated
struct drm_device *dev = crtc->dev;
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
enum omap_channel channel = omap_crtc->channel;
- struct omap_irq_wait *wait = NULL;
+ struct omap_irq_wait *wait;
+ u32 framedone_irq, vsync_irq;
+ int ret;
if (dispc_mgr_is_enabled(channel) == enable)
return;
- /* ignore sync-lost irqs during enable/disable */
+ /*
+ * Digit output produces some sync lost interrupts during the first
+ * frame when enabling, so we need to ignore those.
+ */
omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
- if (dispc_mgr_get_framedone_irq(channel)) {
- if (!enable) {
- wait = omap_irq_wait_init(dev,
- dispc_mgr_get_framedone_irq(channel), 1);
- }
+ framedone_irq = dispc_mgr_get_framedone_irq(channel);
+ vsync_irq = dispc_mgr_get_vsync_irq(channel);
+
+ if (enable) {
+ wait = omap_irq_wait_init(dev, vsync_irq, 1);
} else {
/*
- * When we disable digit output, we need to wait until fields
- * are done. Otherwise the DSS is still working, and turning
- * off the clocks prevents DSS from going to OFF mode. And when
- * enabling, we need to wait for the extra sync losts
+ * When we disable the digit output, we need to wait for
+ * FRAMEDONE to know that DISPC has finished with the output.
+ *
+ * OMAP2/3 does not have FRAMEDONE irq for digit output, and in
+ * that case we need to use vsync interrupt, and wait for both
+ * even and odd frames.
*/
- wait = omap_irq_wait_init(dev,
- dispc_mgr_get_vsync_irq(channel), 2);
+
+ if (framedone_irq)
+ wait = omap_irq_wait_init(dev, framedone_irq, 1);
+ else
+ wait = omap_irq_wait_init(dev, vsync_irq, 2);
}
dispc_mgr_enable(channel, enable);
- if (wait) {
- int ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
- if (ret) {
- dev_err(dev->dev, "%s: timeout waiting for %s\n",
- omap_crtc->name, enable ? "enable" : "disable");
- }
+ ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
+ if (ret) {
+ dev_err(dev->dev, "%s: timeout waiting for %s\n",
+ omap_crtc->name, enable ? "enable" : "disable");
}
omap_irq_register(crtc->dev, &omap_crtc->error_irq);
}
}
+ if (omap_crtc->current_encoder && encoder != omap_crtc->current_encoder)
+ omap_encoder_set_enabled(omap_crtc->current_encoder, false);
+
+ omap_crtc->current_encoder = encoder;
+
if (!omap_crtc->enabled) {
- set_enabled(&omap_crtc->base, false);
if (encoder)
omap_encoder_set_enabled(encoder, false);
} else {
omap_encoder_update(encoder, omap_crtc->mgr,
&omap_crtc->timings);
omap_encoder_set_enabled(encoder, true);
- omap_crtc->full_update = false;
}
-
- dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info);
- dispc_mgr_set_timings(omap_crtc->channel,
- &omap_crtc->timings);
- set_enabled(&omap_crtc->base, true);
}
omap_crtc->full_update = false;
/* nothing needed for post-apply */
}
+void omap_crtc_flush(struct drm_crtc *crtc)
+{
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+ int loops = 0;
+
+ while (!list_empty(&omap_crtc->pending_applies) ||
+ !list_empty(&omap_crtc->queued_applies) ||
+ omap_crtc->event || omap_crtc->old_fb) {
+
+ if (++loops > 10) {
+ dev_err(crtc->dev->dev,
+ "omap_crtc_flush() timeout\n");
+ break;
+ }
+
+ schedule_timeout_uninterruptible(msecs_to_jiffies(20));
+ }
+}
+
static const char *channel_names[] = {
[OMAP_DSS_CHANNEL_LCD] = "lcd",
[OMAP_DSS_CHANNEL_DIGIT] = "tv",
[OMAP_DSS_CHANNEL_LCD2] = "lcd2",
+ [OMAP_DSS_CHANNEL_LCD3] = "lcd3",
};
void omap_crtc_pre_init(void)
static int dev_unload(struct drm_device *dev)
{
struct omap_drm_private *priv = dev->dev_private;
+ int i;
DBG("unload: dev=%p", dev);
drm_kms_helper_poll_fini(dev);
omap_fbdev_free(dev);
+
+ /* flush crtcs so the fbs get released */
+ for (i = 0; i < priv->num_crtcs; i++)
+ omap_crtc_flush(priv->crtcs[i]);
+
omap_modeset_free(dev);
omap_gem_deinit(dev);
{
DBG("");
+ drm_put_dev(platform_get_drvdata(device));
+
omap_disconnect_dssdevs();
omap_crtc_pre_uninit();
- drm_put_dev(platform_get_drvdata(device));
return 0;
}
static int __init omap_drm_init(void)
{
+ int r;
+
DBG("init");
- if (platform_driver_register(&omap_dmm_driver)) {
- /* we can continue on without DMM.. so not fatal */
- dev_err(NULL, "DMM registration failed\n");
+
+ r = platform_driver_register(&omap_dmm_driver);
+ if (r) {
+ pr_err("DMM driver registration failed\n");
+ return r;
+ }
+
+ r = platform_driver_register(&pdev);
+ if (r) {
+ pr_err("omapdrm driver registration failed\n");
+ platform_driver_unregister(&omap_dmm_driver);
+ return r;
}
- return platform_driver_register(&pdev);
+
+ return 0;
}
static void __exit omap_drm_fini(void)
{
DBG("fini");
+
platform_driver_unregister(&pdev);
+
+ platform_driver_unregister(&omap_dmm_driver);
}
/* need late_initcall() so we load after dss_driver's are loaded */
void omap_crtc_pre_uninit(void);
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
struct drm_plane *plane, enum omap_channel channel, int id);
+void omap_crtc_flush(struct drm_crtc *crtc);
struct drm_plane *omap_plane_init(struct drm_device *dev,
int plane_id, bool private_plane);
info->rotation_type = OMAP_DSS_ROT_TILER;
info->screen_width = omap_gem_tiled_stride(plane->bo, orient);
} else {
+ switch (win->rotation & 0xf) {
+ case 0:
+ case BIT(DRM_ROTATE_0):
+ /* OK */
+ break;
+
+ default:
+ dev_warn(fb->dev->dev,
+ "rotation '%d' ignored for non-tiled fb\n",
+ win->rotation);
+ win->rotation = 0;
+ break;
+ }
+
info->paddr = get_linear_addr(plane, format, 0, x, y);
info->rotation_type = OMAP_DSS_ROT_DMA;
info->screen_width = plane->pitch;
fbdev = to_omap_fbdev(priv->fbdev);
+ /* release the ref taken in omap_fbdev_create() */
+ omap_gem_put_paddr(fbdev->bo);
+
/* this will free the backing object */
if (fbdev->fb) {
drm_framebuffer_unregister_private(fbdev->fb);
#ifdef CONFIG_DEBUG_FS
void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
{
- struct drm_device *dev = obj->dev;
struct omap_gem_object *omap_obj = to_omap_bo(obj);
uint64_t off;
- WARN_ON(!mutex_is_locked(&dev->struct_mutex));
-
off = drm_vma_node_start(&obj->vma_node);
seq_printf(m, "%08x: %2d (%2d) %08llx %08Zx (%2d) %p %4d",
{
struct omap_gem_object *omap_obj = waiter->omap_obj;
if ((waiter->op & OMAP_GEM_READ) &&
- (omap_obj->sync->read_complete < waiter->read_target))
+ (omap_obj->sync->write_complete < waiter->write_target))
return true;
if ((waiter->op & OMAP_GEM_WRITE) &&
- (omap_obj->sync->write_complete < waiter->write_target))
+ (omap_obj->sync->read_complete < waiter->read_target))
return true;
return false;
}
}
spin_unlock(&sync_lock);
+
+ kfree(waiter);
}
/* no waiting.. */
omap_plane->apply_done_cb.arg = arg;
}
+ if (plane->fb)
+ drm_framebuffer_unreference(plane->fb);
+
+ drm_framebuffer_reference(fb);
+
plane->fb = fb;
plane->crtc = crtc;
struct omap_plane *omap_plane = to_omap_plane(plane);
omap_plane->enabled = true;
- if (plane->fb)
- drm_framebuffer_unreference(plane->fb);
-
- drm_framebuffer_reference(fb);
+ /* omap_plane_mode_set() takes adjusted src */
+ switch (omap_plane->win.rotation & 0xf) {
+ case BIT(DRM_ROTATE_90):
+ case BIT(DRM_ROTATE_270):
+ swap(src_w, src_h);
+ break;
+ }
return omap_plane_mode_set(plane, crtc, fb,
crtc_x, crtc_y, crtc_w, crtc_h,
return recv_bytes;
}
-#define HEADER_SIZE 4
+#define BARE_ADDRESS_SIZE 3
+#define HEADER_SIZE (BARE_ADDRESS_SIZE + 1)
static ssize_t
radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
tx_buf[0] = msg->address & 0xff;
tx_buf[1] = msg->address >> 8;
tx_buf[2] = msg->request << 4;
- tx_buf[3] = msg->size - 1;
+ tx_buf[3] = msg->size ? (msg->size - 1) : 0;
switch (msg->request & ~DP_AUX_I2C_MOT) {
case DP_AUX_NATIVE_WRITE:
case DP_AUX_I2C_WRITE:
+ /* tx_size needs to be 4 even for bare address packets since the atom
+ * table needs the info in tx_buf[3].
+ */
tx_size = HEADER_SIZE + msg->size;
- tx_buf[3] |= tx_size << 4;
+ if (msg->size == 0)
+ tx_buf[3] |= BARE_ADDRESS_SIZE << 4;
+ else
+ tx_buf[3] |= tx_size << 4;
memcpy(tx_buf + HEADER_SIZE, msg->buffer, msg->size);
ret = radeon_process_aux_ch(chan,
tx_buf, tx_size, NULL, 0, delay, &ack);
break;
case DP_AUX_NATIVE_READ:
case DP_AUX_I2C_READ:
+ /* tx_size needs to be 4 even for bare address packets since the atom
+ * table needs the info in tx_buf[3].
+ */
tx_size = HEADER_SIZE;
- tx_buf[3] |= tx_size << 4;
+ if (msg->size == 0)
+ tx_buf[3] |= BARE_ADDRESS_SIZE << 4;
+ else
+ tx_buf[3] |= tx_size << 4;
ret = radeon_process_aux_ch(chan,
tx_buf, tx_size, msg->buffer, msg->size, delay, &ack);
break;
break;
}
- if (ret > 0)
+ if (ret >= 0)
msg->reply = ack >> 4;
return ret;
void radeon_dp_aux_init(struct radeon_connector *radeon_connector)
{
- struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
-
- dig_connector->dp_i2c_bus->aux.dev = radeon_connector->base.kdev;
- dig_connector->dp_i2c_bus->aux.transfer = radeon_dp_aux_transfer;
-}
-
-int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
- u8 write_byte, u8 *read_byte)
-{
- struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
- struct radeon_i2c_chan *auxch = i2c_get_adapdata(adapter);
- u16 address = algo_data->address;
- u8 msg[5];
- u8 reply[2];
- unsigned retry;
- int msg_bytes;
- int reply_bytes = 1;
int ret;
- u8 ack;
-
- /* Set up the address */
- msg[0] = address;
- msg[1] = address >> 8;
-
- /* Set up the command byte */
- if (mode & MODE_I2C_READ) {
- msg[2] = DP_AUX_I2C_READ << 4;
- msg_bytes = 4;
- msg[3] = msg_bytes << 4;
- } else {
- msg[2] = DP_AUX_I2C_WRITE << 4;
- msg_bytes = 5;
- msg[3] = msg_bytes << 4;
- msg[4] = write_byte;
- }
-
- /* special handling for start/stop */
- if (mode & (MODE_I2C_START | MODE_I2C_STOP))
- msg[3] = 3 << 4;
-
- /* Set MOT bit for all but stop */
- if ((mode & MODE_I2C_STOP) == 0)
- msg[2] |= DP_AUX_I2C_MOT << 4;
-
- for (retry = 0; retry < 7; retry++) {
- ret = radeon_process_aux_ch(auxch,
- msg, msg_bytes, reply, reply_bytes, 0, &ack);
- if (ret == -EBUSY)
- continue;
- else if (ret < 0) {
- DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
- return ret;
- }
-
- switch ((ack >> 4) & DP_AUX_NATIVE_REPLY_MASK) {
- case DP_AUX_NATIVE_REPLY_ACK:
- /* I2C-over-AUX Reply field is only valid
- * when paired with AUX ACK.
- */
- break;
- case DP_AUX_NATIVE_REPLY_NACK:
- DRM_DEBUG_KMS("aux_ch native nack\n");
- return -EREMOTEIO;
- case DP_AUX_NATIVE_REPLY_DEFER:
- DRM_DEBUG_KMS("aux_ch native defer\n");
- usleep_range(500, 600);
- continue;
- default:
- DRM_ERROR("aux_ch invalid native reply 0x%02x\n", ack);
- return -EREMOTEIO;
- }
- switch ((ack >> 4) & DP_AUX_I2C_REPLY_MASK) {
- case DP_AUX_I2C_REPLY_ACK:
- if (mode == MODE_I2C_READ)
- *read_byte = reply[0];
- return ret;
- case DP_AUX_I2C_REPLY_NACK:
- DRM_DEBUG_KMS("aux_i2c nack\n");
- return -EREMOTEIO;
- case DP_AUX_I2C_REPLY_DEFER:
- DRM_DEBUG_KMS("aux_i2c defer\n");
- usleep_range(400, 500);
- break;
- default:
- DRM_ERROR("aux_i2c invalid reply 0x%02x\n", ack);
- return -EREMOTEIO;
- }
- }
+ radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd;
+ radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev;
+ radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer;
+ ret = drm_dp_aux_register_i2c_bus(&radeon_connector->ddc_bus->aux);
+ if (!ret)
+ radeon_connector->ddc_bus->has_aux = true;
- DRM_DEBUG_KMS("aux i2c too many retries, giving up\n");
- return -EREMOTEIO;
+ WARN(ret, "drm_dp_aux_register_i2c_bus() failed with error %d\n", ret);
}
/***** general DP utility functions *****/
u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
{
- struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
struct drm_device *dev = radeon_connector->base.dev;
struct radeon_device *rdev = dev->dev_private;
return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
- dig_connector->dp_i2c_bus->rec.i2c_id, 0);
+ radeon_connector->ddc_bus->rec.i2c_id, 0);
}
static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
return;
- if (drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_SINK_OUI, buf, 3))
+ if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3))
DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);
- if (drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_BRANCH_OUI, buf, 3))
+ if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3))
DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);
}
u8 msg[DP_DPCD_SIZE];
int ret, i;
- ret = drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_DPCD_REV, msg,
+ ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg,
DP_DPCD_SIZE);
if (ret > 0) {
memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
/* DP bridge chips */
- drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux,
+ drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
DP_EDP_CONFIGURATION_CAP, &tmp);
if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
} else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
/* eDP */
- drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux,
+ drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
DP_EDP_CONFIGURATION_CAP, &tmp);
if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
u8 link_status[DP_LINK_STATUS_SIZE];
struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
- if (drm_dp_dpcd_read_link_status(&dig->dp_i2c_bus->aux, link_status) <= 0)
+ if (drm_dp_dpcd_read_link_status(&radeon_connector->ddc_bus->aux, link_status)
+ <= 0)
return false;
if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count))
return false;
/* power up/down the sink */
if (dig_connector->dpcd[0] >= 0x11) {
- drm_dp_dpcd_writeb(&dig_connector->dp_i2c_bus->aux,
+ drm_dp_dpcd_writeb(&radeon_connector->ddc_bus->aux,
DP_SET_POWER, power_state);
usleep_range(1000, 2000);
}
else
dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
- drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux, DP_MAX_LANE_COUNT, &tmp);
+ drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp);
if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
dp_info.tp3_supported = true;
else
dp_info.connector = connector;
dp_info.dp_lane_count = dig_connector->dp_lane_count;
dp_info.dp_clock = dig_connector->dp_clock;
- dp_info.aux = &dig_connector->dp_i2c_bus->aux;
+ dp_info.aux = &radeon_connector->ddc_bus->aux;
if (radeon_dp_link_train_init(&dp_info))
goto done;
*
*/
+#include <linux/firmware.h>
#include "drmP.h"
#include "radeon.h"
+#include "radeon_ucode.h"
#include "cikd.h"
#include "r600_dpm.h"
#include "ci_dpm.h"
struct ci_power_info *pi = ci_get_pi(rdev);
switch (rdev->pdev->device) {
+ case 0x6649:
case 0x6650:
+ case 0x6651:
case 0x6658:
case 0x665C:
+ case 0x665D:
default:
pi->powertune_defaults = &defaults_bonaire_xt;
break;
- case 0x6651:
- case 0x665D:
- pi->powertune_defaults = &defaults_bonaire_pro;
- break;
case 0x6640:
- pi->powertune_defaults = &defaults_saturn_xt;
- break;
case 0x6641:
- pi->powertune_defaults = &defaults_saturn_pro;
+ case 0x6646:
+ case 0x6647:
+ pi->powertune_defaults = &defaults_saturn_xt;
break;
case 0x67B8:
case 0x67B0:
+ pi->powertune_defaults = &defaults_hawaii_xt;
+ break;
+ case 0x67BA:
+ case 0x67B1:
+ pi->powertune_defaults = &defaults_hawaii_pro;
+ break;
case 0x67A0:
case 0x67A1:
case 0x67A2:
case 0x67AA:
case 0x67B9:
case 0x67BE:
- pi->powertune_defaults = &defaults_hawaii_xt;
- break;
- case 0x67BA:
- case 0x67B1:
- pi->powertune_defaults = &defaults_hawaii_pro;
+ pi->powertune_defaults = &defaults_bonaire_xt;
break;
}
pi->mclk_dpm_key_disabled = 0;
pi->pcie_dpm_key_disabled = 0;
+ /* mclk dpm is unstable on some R7 260X cards with the old mc ucode */
+ if ((rdev->pdev->device == 0x6658) &&
+ (rdev->mc_fw->size == (BONAIRE_MC_UCODE_SIZE * 4))) {
+ pi->mclk_dpm_key_disabled = 1;
+ }
+
pi->caps_sclk_ds = true;
pi->mclk_strobe_mode_threshold = 40000;
MODULE_FIRMWARE("radeon/BONAIRE_ce.bin");
MODULE_FIRMWARE("radeon/BONAIRE_mec.bin");
MODULE_FIRMWARE("radeon/BONAIRE_mc.bin");
+MODULE_FIRMWARE("radeon/BONAIRE_mc2.bin");
MODULE_FIRMWARE("radeon/BONAIRE_rlc.bin");
MODULE_FIRMWARE("radeon/BONAIRE_sdma.bin");
MODULE_FIRMWARE("radeon/BONAIRE_smc.bin");
MODULE_FIRMWARE("radeon/HAWAII_ce.bin");
MODULE_FIRMWARE("radeon/HAWAII_mec.bin");
MODULE_FIRMWARE("radeon/HAWAII_mc.bin");
+MODULE_FIRMWARE("radeon/HAWAII_mc2.bin");
MODULE_FIRMWARE("radeon/HAWAII_rlc.bin");
MODULE_FIRMWARE("radeon/HAWAII_sdma.bin");
MODULE_FIRMWARE("radeon/HAWAII_smc.bin");
const __be32 *fw_data;
u32 running, blackout = 0;
u32 *io_mc_regs;
- int i, ucode_size, regs_size;
+ int i, regs_size, ucode_size;
if (!rdev->mc_fw)
return -EINVAL;
+ ucode_size = rdev->mc_fw->size / 4;
+
switch (rdev->family) {
case CHIP_BONAIRE:
io_mc_regs = (u32 *)&bonaire_io_mc_regs;
- ucode_size = CIK_MC_UCODE_SIZE;
regs_size = BONAIRE_IO_MC_REGS_SIZE;
break;
case CHIP_HAWAII:
io_mc_regs = (u32 *)&hawaii_io_mc_regs;
- ucode_size = HAWAII_MC_UCODE_SIZE;
regs_size = HAWAII_IO_MC_REGS_SIZE;
break;
default:
const char *chip_name;
size_t pfp_req_size, me_req_size, ce_req_size,
mec_req_size, rlc_req_size, mc_req_size = 0,
- sdma_req_size, smc_req_size = 0;
+ sdma_req_size, smc_req_size = 0, mc2_req_size = 0;
char fw_name[30];
int err;
ce_req_size = CIK_CE_UCODE_SIZE * 4;
mec_req_size = CIK_MEC_UCODE_SIZE * 4;
rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4;
- mc_req_size = CIK_MC_UCODE_SIZE * 4;
+ mc_req_size = BONAIRE_MC_UCODE_SIZE * 4;
+ mc2_req_size = BONAIRE_MC2_UCODE_SIZE * 4;
sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
smc_req_size = ALIGN(BONAIRE_SMC_UCODE_SIZE, 4);
break;
mec_req_size = CIK_MEC_UCODE_SIZE * 4;
rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4;
mc_req_size = HAWAII_MC_UCODE_SIZE * 4;
+ mc2_req_size = HAWAII_MC2_UCODE_SIZE * 4;
sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
smc_req_size = ALIGN(HAWAII_SMC_UCODE_SIZE, 4);
break;
/* No SMC, MC ucode on APUs */
if (!(rdev->flags & RADEON_IS_IGP)) {
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
- if (err)
- goto out;
- if (rdev->mc_fw->size != mc_req_size) {
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+ err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ }
+ if ((rdev->mc_fw->size != mc_req_size) &&
+ (rdev->mc_fw->size != mc2_req_size)){
printk(KERN_ERR
"cik_mc: Bogus length %zu in firmware \"%s\"\n",
rdev->mc_fw->size, fw_name);
err = -EINVAL;
}
+ DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
tmp = 0xCAFEDEAD;
writel(tmp, ptr);
- r = radeon_ring_lock(rdev, ring, 4);
+ r = radeon_ring_lock(rdev, ring, 5);
if (r) {
DRM_ERROR("radeon: dma failed to lock ring %d (%d).\n", ring->idx, r);
return r;
rdev->audio.enabled = true;
- if (ASIC_IS_DCE8(rdev))
+ if (ASIC_IS_DCE81(rdev)) /* KV: 4 streams, 7 endpoints */
+ rdev->audio.num_pins = 7;
+ else if (ASIC_IS_DCE83(rdev)) /* KB: 2 streams, 3 endpoints */
+ rdev->audio.num_pins = 3;
+ else if (ASIC_IS_DCE8(rdev)) /* BN/HW: 6 streams, 7 endpoints */
+ rdev->audio.num_pins = 7;
+ else if (ASIC_IS_DCE61(rdev)) /* TN: 4 streams, 6 endpoints */
rdev->audio.num_pins = 6;
- else if (ASIC_IS_DCE61(rdev))
- rdev->audio.num_pins = 4;
- else
+ else if (ASIC_IS_DCE64(rdev)) /* OL: 2 streams, 2 endpoints */
+ rdev->audio.num_pins = 2;
+ else /* SI: 6 streams, 6 endpoints */
rdev->audio.num_pins = 6;
for (i = 0; i < rdev->audio.num_pins; i++) {
u32 line_time_us, vblank_lines;
u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- radeon_crtc = to_radeon_crtc(crtc);
- if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
- line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) /
- radeon_crtc->hw_mode.clock;
- vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end -
- radeon_crtc->hw_mode.crtc_vdisplay +
- (radeon_crtc->v_border * 2);
- vblank_time_us = vblank_lines * line_time_us;
- break;
+ if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ radeon_crtc = to_radeon_crtc(crtc);
+ if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
+ line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) /
+ radeon_crtc->hw_mode.clock;
+ vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end -
+ radeon_crtc->hw_mode.crtc_vdisplay +
+ (radeon_crtc->v_border * 2);
+ vblank_time_us = vblank_lines * line_time_us;
+ break;
+ }
}
}
struct radeon_crtc *radeon_crtc;
u32 vrefresh = 0;
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- radeon_crtc = to_radeon_crtc(crtc);
- if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
- vrefresh = radeon_crtc->hw_mode.vrefresh;
- break;
+ if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ radeon_crtc = to_radeon_crtc(crtc);
+ if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
+ vrefresh = radeon_crtc->hw_mode.vrefresh;
+ break;
+ }
}
}
-
return vrefresh;
}
struct cik_irq_stat_regs cik;
};
-#define RADEON_MAX_HPD_PINS 6
+#define RADEON_MAX_HPD_PINS 7
#define RADEON_MAX_CRTCS 6
#define RADEON_MAX_AFMT_BLOCKS 7
bool have_disp_power_ref;
};
+bool radeon_is_px(struct drm_device *dev);
int radeon_device_init(struct radeon_device *rdev,
struct drm_device *ddev,
struct pci_dev *pdev,
#define ASIC_IS_DCE64(rdev) ((rdev->family == CHIP_OLAND))
#define ASIC_IS_NODCE(rdev) ((rdev->family == CHIP_HAINAN))
#define ASIC_IS_DCE8(rdev) ((rdev->family >= CHIP_BONAIRE))
+#define ASIC_IS_DCE81(rdev) ((rdev->family == CHIP_KAVERI))
+#define ASIC_IS_DCE82(rdev) ((rdev->family == CHIP_BONAIRE))
+#define ASIC_IS_DCE83(rdev) ((rdev->family == CHIP_KABINI))
#define ASIC_IS_LOMBOK(rdev) ((rdev->ddev->pdev->device == 0x6849) || \
(rdev->ddev->pdev->device == 0x6850) || \
u16 mux;
} __packed;
-bool radeon_is_px(void) {
+bool radeon_has_atpx(void) {
return radeon_atpx_priv.atpx_detected;
}
has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
}
+ /* some newer PX laptops mark the dGPU as a non-VGA display device */
+ while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
+ vga_count++;
+
+ has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
+ }
+
if (has_atpx && vga_count == 2) {
acpi_get_name(radeon_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer);
printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n",
.force = radeon_dvi_force,
};
-static void radeon_dp_connector_destroy(struct drm_connector *connector)
-{
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
-
- if (radeon_connector->edid)
- kfree(radeon_connector->edid);
- if (radeon_dig_connector->dp_i2c_bus)
- radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus);
- kfree(radeon_connector->con_priv);
- drm_sysfs_connector_remove(connector);
- drm_connector_cleanup(connector);
- kfree(connector);
-}
-
static int radeon_dp_get_modes(struct drm_connector *connector)
{
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
.detect = radeon_dp_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = radeon_connector_set_property,
- .destroy = radeon_dp_connector_destroy,
+ .destroy = radeon_connector_destroy,
.force = radeon_dvi_force,
};
.detect = radeon_dp_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = radeon_lvds_set_property,
- .destroy = radeon_dp_connector_destroy,
+ .destroy = radeon_connector_destroy,
.force = radeon_dvi_force,
};
.detect = radeon_dp_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = radeon_lvds_set_property,
- .destroy = radeon_dp_connector_destroy,
+ .destroy = radeon_connector_destroy,
.force = radeon_dvi_force,
};
radeon_dig_connector->igp_lane_info = igp_lane_info;
radeon_connector->con_priv = radeon_dig_connector;
if (i2c_bus->valid) {
- /* add DP i2c bus */
- if (connector_type == DRM_MODE_CONNECTOR_eDP)
- radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
- else
- radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
- if (radeon_dig_connector->dp_i2c_bus)
+ radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+ if (radeon_connector->ddc_bus)
has_aux = true;
else
- DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
- radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
- if (!radeon_connector->ddc_bus)
DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
}
switch (connector_type) {
drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
if (i2c_bus->valid) {
- /* add DP i2c bus */
- radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
- if (!radeon_dig_connector->dp_i2c_bus)
- DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
if (radeon_connector->ddc_bus)
has_aux = true;
drm_connector_init(dev, &radeon_connector->base, &radeon_edp_connector_funcs, connector_type);
drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
if (i2c_bus->valid) {
- /* add DP i2c bus */
- radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
- if (radeon_dig_connector->dp_i2c_bus)
+ radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+ if (radeon_connector->ddc_bus)
has_aux = true;
else
- DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
- radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
- if (!radeon_connector->ddc_bus)
DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
}
drm_object_attach_property(&radeon_connector->base.base,
"LAST",
};
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_is_px(void);
-#else
-static inline bool radeon_is_px(void) { return false; }
-#endif
+bool radeon_is_px(struct drm_device *dev)
+{
+ struct radeon_device *rdev = dev->dev_private;
+
+ if (rdev->flags & RADEON_IS_PX)
+ return true;
+ return false;
+}
/**
* radeon_program_register_sequence - program an array of registers.
{
struct drm_device *dev = pci_get_drvdata(pdev);
- if (radeon_is_px() && state == VGA_SWITCHEROO_OFF)
+ if (radeon_is_px(dev) && state == VGA_SWITCHEROO_OFF)
return;
if (state == VGA_SWITCHEROO_ON) {
* ignore it */
vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
- if (radeon_runtime_pm == 1)
- runtime = true;
- if ((radeon_runtime_pm == -1) && radeon_is_px())
+ if (rdev->flags & RADEON_IS_PX)
runtime = true;
vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime);
if (runtime)
if (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) !=
ENCODER_OBJECT_ID_NONE) {
- struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
-
- if (dig->dp_i2c_bus)
+ if (radeon_connector->ddc_bus->has_aux)
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
- &dig->dp_i2c_bus->adapter);
+ &radeon_connector->ddc_bus->aux.ddc);
} else if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
(radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
- dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus)
+ dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
+ radeon_connector->ddc_bus->has_aux)
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
- &dig->dp_i2c_bus->adapter);
+ &radeon_connector->ddc_bus->aux.ddc);
else if (radeon_connector->ddc_bus && !radeon_connector->edid)
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
&radeon_connector->ddc_bus->adapter);
}
}
+/**
+ * avivo_get_fb_ref_div - feedback and ref divider calculation
+ *
+ * @nom: nominator
+ * @den: denominator
+ * @post_div: post divider
+ * @fb_div_max: feedback divider maximum
+ * @ref_div_max: reference divider maximum
+ * @fb_div: resulting feedback divider
+ * @ref_div: resulting reference divider
+ *
+ * Calculate feedback and reference divider for a given post divider. Makes
+ * sure we stay within the limits.
+ */
+static void avivo_get_fb_ref_div(unsigned nom, unsigned den, unsigned post_div,
+ unsigned fb_div_max, unsigned ref_div_max,
+ unsigned *fb_div, unsigned *ref_div)
+{
+ /* limit reference * post divider to a maximum */
+ ref_div_max = min(210 / post_div, ref_div_max);
+
+ /* get matching reference and feedback divider */
+ *ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max);
+ *fb_div = DIV_ROUND_CLOSEST(nom * *ref_div * post_div, den);
+
+ /* limit fb divider to its maximum */
+ if (*fb_div > fb_div_max) {
+ *ref_div = DIV_ROUND_CLOSEST(*ref_div * fb_div_max, *fb_div);
+ *fb_div = fb_div_max;
+ }
+}
+
/**
* radeon_compute_pll_avivo - compute PLL paramaters
*
u32 *ref_div_p,
u32 *post_div_p)
{
+ unsigned target_clock = pll->flags & RADEON_PLL_USE_FRAC_FB_DIV ?
+ freq : freq / 10;
+
unsigned fb_div_min, fb_div_max, fb_div;
unsigned post_div_min, post_div_max, post_div;
unsigned ref_div_min, ref_div_max, ref_div;
unsigned post_div_best, diff_best;
- unsigned nom, den, tmp;
+ unsigned nom, den;
/* determine allowed feedback divider range */
fb_div_min = pll->min_feedback_div;
ref_div_min = pll->reference_div;
else
ref_div_min = pll->min_ref_div;
- ref_div_max = pll->max_ref_div;
+
+ if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV &&
+ pll->flags & RADEON_PLL_USE_REF_DIV)
+ ref_div_max = pll->reference_div;
+ else
+ ref_div_max = pll->max_ref_div;
/* determine allowed post divider range */
if (pll->flags & RADEON_PLL_USE_POST_DIV) {
post_div_min = pll->post_div;
post_div_max = pll->post_div;
} else {
- unsigned target_clock = freq / 10;
unsigned vco_min, vco_max;
if (pll->flags & RADEON_PLL_IS_LCD) {
vco_max = pll->pll_out_max;
}
+ if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
+ vco_min *= 10;
+ vco_max *= 10;
+ }
+
post_div_min = vco_min / target_clock;
if ((target_clock * post_div_min) < vco_min)
++post_div_min;
}
/* represent the searched ratio as fractional number */
- nom = pll->flags & RADEON_PLL_USE_FRAC_FB_DIV ? freq : freq / 10;
+ nom = target_clock;
den = pll->reference_freq;
/* reduce the numbers to a simpler ratio */
diff_best = ~0;
for (post_div = post_div_min; post_div <= post_div_max; ++post_div) {
- unsigned diff = abs(den - den / post_div * post_div);
+ unsigned diff;
+ avivo_get_fb_ref_div(nom, den, post_div, fb_div_max,
+ ref_div_max, &fb_div, &ref_div);
+ diff = abs(target_clock - (pll->reference_freq * fb_div) /
+ (ref_div * post_div));
+
if (diff < diff_best || (diff == diff_best &&
!(pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP))) {
}
post_div = post_div_best;
- /* get matching reference and feedback divider */
- ref_div = max(den / post_div, 1u);
- fb_div = nom;
-
- /* we're almost done, but reference and feedback
- divider might be to large now */
-
- tmp = ref_div;
-
- if (fb_div > fb_div_max) {
- ref_div = ref_div * fb_div_max / fb_div;
- fb_div = fb_div_max;
- }
-
- if (ref_div > ref_div_max) {
- ref_div = ref_div_max;
- fb_div = nom * ref_div_max / tmp;
- }
+ /* get the feedback and reference divider for the optimal value */
+ avivo_get_fb_ref_div(nom, den, post_div, fb_div_max, ref_div_max,
+ &fb_div, &ref_div);
/* reduce the numbers to a simpler ratio once more */
/* this also makes sure that the reference divider is large enough */
*post_div_p = post_div;
DRM_DEBUG_KMS("%d - %d, pll dividers - fb: %d.%d ref: %d, post %d\n",
- freq, *dot_clock_p, *fb_div_p, *frac_fb_div_p,
+ freq, *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p,
ref_div, post_div);
}
unsigned int flags,
int *vpos, int *hpos, ktime_t *stime,
ktime_t *etime);
+extern bool radeon_is_px(struct drm_device *dev);
extern const struct drm_ioctl_desc radeon_ioctls_kms[];
extern int radeon_max_kms_ioctl;
int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
#if defined(CONFIG_VGA_SWITCHEROO)
void radeon_register_atpx_handler(void);
void radeon_unregister_atpx_handler(void);
-bool radeon_is_px(void);
#else
static inline void radeon_register_atpx_handler(void) {}
static inline void radeon_unregister_atpx_handler(void) {}
-static inline bool radeon_is_px(void) { return false; }
#endif
int radeon_no_wb;
MODULE_PARM_DESC(r4xx_atom, "Enable ATOMBIOS modesetting for R4xx");
module_param_named(r4xx_atom, radeon_r4xx_atom, int, 0444);
-MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing");
+MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");
module_param_named(vramlimit, radeon_vram_limit, int, 0600);
MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)");
struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret;
- if (radeon_runtime_pm == 0) {
- pm_runtime_forbid(dev);
- return -EBUSY;
- }
-
- if (radeon_runtime_pm == -1 && !radeon_is_px()) {
+ if (!radeon_is_px(drm_dev)) {
pm_runtime_forbid(dev);
return -EBUSY;
}
struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret;
- if (radeon_runtime_pm == 0)
- return -EINVAL;
-
- if (radeon_runtime_pm == -1 && !radeon_is_px())
+ if (!radeon_is_px(drm_dev))
return -EINVAL;
drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct drm_crtc *crtc;
- if (radeon_runtime_pm == 0) {
- pm_runtime_forbid(dev);
- return -EBUSY;
- }
-
- /* are we PX enabled? */
- if (radeon_runtime_pm == -1 && !radeon_is_px()) {
- DRM_DEBUG_DRIVER("failing to power off - not px\n");
+ if (!radeon_is_px(drm_dev)) {
pm_runtime_forbid(dev);
return -EBUSY;
}
RADEON_NEW_MEMMAP = 0x00400000UL,
RADEON_IS_PCI = 0x00800000UL,
RADEON_IS_IGPGART = 0x01000000UL,
+ RADEON_IS_PX = 0x02000000UL,
};
#endif
radeon_router_select_ddc_port(radeon_connector);
if (use_aux) {
- struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
- ret = i2c_transfer(&dig->dp_i2c_bus->adapter, msgs, 2);
+ ret = i2c_transfer(&radeon_connector->ddc_bus->aux.ddc, msgs, 2);
} else {
ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2);
}
/* set the radeon bit adapter */
snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
"Radeon i2c bit bus %s", name);
- i2c->adapter.algo_data = &i2c->algo.bit;
- i2c->algo.bit.pre_xfer = pre_xfer;
- i2c->algo.bit.post_xfer = post_xfer;
- i2c->algo.bit.setsda = set_data;
- i2c->algo.bit.setscl = set_clock;
- i2c->algo.bit.getsda = get_data;
- i2c->algo.bit.getscl = get_clock;
- i2c->algo.bit.udelay = 10;
- i2c->algo.bit.timeout = usecs_to_jiffies(2200); /* from VESA */
- i2c->algo.bit.data = i2c;
+ i2c->adapter.algo_data = &i2c->bit;
+ i2c->bit.pre_xfer = pre_xfer;
+ i2c->bit.post_xfer = post_xfer;
+ i2c->bit.setsda = set_data;
+ i2c->bit.setscl = set_clock;
+ i2c->bit.getsda = get_data;
+ i2c->bit.getscl = get_clock;
+ i2c->bit.udelay = 10;
+ i2c->bit.timeout = usecs_to_jiffies(2200); /* from VESA */
+ i2c->bit.data = i2c;
ret = i2c_bit_add_bus(&i2c->adapter);
if (ret) {
DRM_ERROR("Failed to register bit i2c %s\n", name);
}
-struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
- struct radeon_i2c_bus_rec *rec,
- const char *name)
-{
- struct radeon_i2c_chan *i2c;
- int ret;
-
- i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL);
- if (i2c == NULL)
- return NULL;
-
- i2c->rec = *rec;
- i2c->adapter.owner = THIS_MODULE;
- i2c->adapter.class = I2C_CLASS_DDC;
- i2c->adapter.dev.parent = &dev->pdev->dev;
- i2c->dev = dev;
- snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
- "Radeon aux bus %s", name);
- i2c_set_adapdata(&i2c->adapter, i2c);
- i2c->adapter.algo_data = &i2c->algo.dp;
- i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch;
- i2c->algo.dp.address = 0;
- ret = i2c_dp_aux_add_bus(&i2c->adapter);
- if (ret) {
- DRM_INFO("Failed to register i2c %s\n", name);
- goto out_free;
- }
-
- return i2c;
-out_free:
- kfree(i2c);
- return NULL;
-
-}
-
void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
{
if (!i2c)
return;
i2c_del_adapter(&i2c->adapter);
+ if (i2c->has_aux)
+ drm_dp_aux_unregister_i2c_bus(&i2c->aux);
kfree(i2c);
}
#include <linux/pm_runtime.h>
#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_is_px(void);
+bool radeon_has_atpx(void);
#else
-static inline bool radeon_is_px(void) { return false; }
+static inline bool radeon_has_atpx(void) { return false; }
#endif
/**
flags |= RADEON_IS_PCI;
}
+ if ((radeon_runtime_pm != 0) &&
+ radeon_has_atpx() &&
+ ((flags & RADEON_IS_IGP) == 0))
+ flags |= RADEON_IS_PX;
+
/* radeon_device_init should report only fatal error
* like memory allocation failure or iomapping failure,
* or memory manager initialization failure, it must
"Error during ACPI methods call\n");
}
- if ((radeon_runtime_pm == 1) ||
- ((radeon_runtime_pm == -1) && radeon_is_px())) {
+ if (radeon_is_px(dev)) {
pm_runtime_use_autosuspend(dev->dev);
pm_runtime_set_autosuspend_delay(dev->dev, 5000);
pm_runtime_set_active(dev->dev);
}
r = radeon_vm_init(rdev, &fpriv->vm);
- if (r)
+ if (r) {
+ kfree(fpriv);
return r;
+ }
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
- if (r)
+ if (r) {
+ radeon_vm_fini(rdev, &fpriv->vm);
+ kfree(fpriv);
return r;
+ }
/* map the ib pool buffer read only into
* virtual address space */
struct radeon_i2c_chan {
struct i2c_adapter adapter;
struct drm_device *dev;
- union {
- struct i2c_algo_bit_data bit;
- struct i2c_algo_dp_aux_data dp;
- } algo;
+ struct i2c_algo_bit_data bit;
struct radeon_i2c_bus_rec rec;
struct drm_dp_aux aux;
+ bool has_aux;
};
/* mostly for macs, but really any system without connector tables */
struct radeon_connector_atom_dig {
uint32_t igp_lane_info;
/* displayport */
- struct radeon_i2c_chan *dp_i2c_bus;
u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 dp_sink_type;
int dp_clock;
uint8_t lane_set);
extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder);
extern struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder);
-extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
- u8 write_byte, u8 *read_byte);
void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
extern void radeon_i2c_init(struct radeon_device *rdev);
const char *name);
extern struct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev,
struct radeon_i2c_bus_rec *i2c_bus);
-extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
- struct radeon_i2c_bus_rec *rec,
- const char *name);
extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
struct radeon_i2c_bus_rec *rec,
const char *name);
static int radeon_hwmon_init(struct radeon_device *rdev)
{
int err = 0;
- struct device *hwmon_dev;
switch (rdev->pm.int_thermal_type) {
case THERMAL_TYPE_RV6XX:
case THERMAL_TYPE_KV:
if (rdev->asic->pm.get_temperature == NULL)
return err;
- hwmon_dev = hwmon_device_register_with_groups(rdev->dev,
- "radeon", rdev,
- hwmon_groups);
- if (IS_ERR(hwmon_dev)) {
- err = PTR_ERR(hwmon_dev);
+ rdev->pm.int_hwmon_dev = hwmon_device_register_with_groups(rdev->dev,
+ "radeon", rdev,
+ hwmon_groups);
+ if (IS_ERR(rdev->pm.int_hwmon_dev)) {
+ err = PTR_ERR(rdev->pm.int_hwmon_dev);
dev_err(rdev->dev,
"Unable to register hwmon device: %d\n", err);
}
return err;
}
+static void radeon_hwmon_fini(struct radeon_device *rdev)
+{
+ if (rdev->pm.int_hwmon_dev)
+ hwmon_device_unregister(rdev->pm.int_hwmon_dev);
+}
+
static void radeon_dpm_thermal_work_handler(struct work_struct *work)
{
struct radeon_device *rdev =
case CHIP_RV670:
case CHIP_RS780:
case CHIP_RS880:
+ case CHIP_RV770:
case CHIP_BARTS:
case CHIP_TURKS:
case CHIP_CAICOS:
else
rdev->pm.pm_method = PM_METHOD_PROFILE;
break;
- case CHIP_RV770:
case CHIP_RV730:
case CHIP_RV710:
case CHIP_RV740:
device_remove_file(rdev->dev, &dev_attr_power_method);
}
+ radeon_hwmon_fini(rdev);
+
if (rdev->pm.power_state)
kfree(rdev->pm.power_state);
}
}
radeon_dpm_fini(rdev);
+ radeon_hwmon_fini(rdev);
+
if (rdev->pm.power_state)
kfree(rdev->pm.power_state);
}
rdev->pm.active_crtcs = 0;
rdev->pm.active_crtc_count = 0;
- list_for_each_entry(crtc,
- &ddev->mode_config.crtc_list, head) {
- radeon_crtc = to_radeon_crtc(crtc);
- if (radeon_crtc->enabled) {
- rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id);
- rdev->pm.active_crtc_count++;
+ if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
+ list_for_each_entry(crtc,
+ &ddev->mode_config.crtc_list, head) {
+ radeon_crtc = to_radeon_crtc(crtc);
+ if (radeon_crtc->enabled) {
+ rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id);
+ rdev->pm.active_crtc_count++;
+ }
}
}
/* update active crtc counts */
rdev->pm.dpm.new_active_crtcs = 0;
rdev->pm.dpm.new_active_crtc_count = 0;
- list_for_each_entry(crtc,
- &ddev->mode_config.crtc_list, head) {
- radeon_crtc = to_radeon_crtc(crtc);
- if (crtc->enabled) {
- rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id);
- rdev->pm.dpm.new_active_crtc_count++;
+ if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
+ list_for_each_entry(crtc,
+ &ddev->mode_config.crtc_list, head) {
+ radeon_crtc = to_radeon_crtc(crtc);
+ if (crtc->enabled) {
+ rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id);
+ rdev->pm.dpm.new_active_crtc_count++;
+ }
}
}
#define BTC_MC_UCODE_SIZE 6024
#define CAYMAN_MC_UCODE_SIZE 6037
#define SI_MC_UCODE_SIZE 7769
+#define TAHITI_MC_UCODE_SIZE 7808
+#define PITCAIRN_MC_UCODE_SIZE 7775
+#define VERDE_MC_UCODE_SIZE 7875
#define OLAND_MC_UCODE_SIZE 7863
-#define CIK_MC_UCODE_SIZE 7866
+#define BONAIRE_MC_UCODE_SIZE 7866
+#define BONAIRE_MC2_UCODE_SIZE 7948
#define HAWAII_MC_UCODE_SIZE 7933
+#define HAWAII_MC2_UCODE_SIZE 8091
/* SDMA */
#define CIK_SDMA_UCODE_SIZE 1050
struct radeon_fence *fence)
{
struct radeon_ring *ring = &rdev->ring[fence->ring];
- uint32_t addr = rdev->fence_drv[fence->ring].gpu_addr;
+ uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
radeon_ring_write(ring, VCE_CMD_FENCE);
radeon_ring_write(ring, addr);
MODULE_FIRMWARE("radeon/TAHITI_me.bin");
MODULE_FIRMWARE("radeon/TAHITI_ce.bin");
MODULE_FIRMWARE("radeon/TAHITI_mc.bin");
+MODULE_FIRMWARE("radeon/TAHITI_mc2.bin");
MODULE_FIRMWARE("radeon/TAHITI_rlc.bin");
MODULE_FIRMWARE("radeon/TAHITI_smc.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_me.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin");
+MODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_smc.bin");
MODULE_FIRMWARE("radeon/VERDE_pfp.bin");
MODULE_FIRMWARE("radeon/VERDE_me.bin");
MODULE_FIRMWARE("radeon/VERDE_ce.bin");
MODULE_FIRMWARE("radeon/VERDE_mc.bin");
+MODULE_FIRMWARE("radeon/VERDE_mc2.bin");
MODULE_FIRMWARE("radeon/VERDE_rlc.bin");
MODULE_FIRMWARE("radeon/VERDE_smc.bin");
MODULE_FIRMWARE("radeon/OLAND_pfp.bin");
MODULE_FIRMWARE("radeon/OLAND_me.bin");
MODULE_FIRMWARE("radeon/OLAND_ce.bin");
MODULE_FIRMWARE("radeon/OLAND_mc.bin");
+MODULE_FIRMWARE("radeon/OLAND_mc2.bin");
MODULE_FIRMWARE("radeon/OLAND_rlc.bin");
MODULE_FIRMWARE("radeon/OLAND_smc.bin");
MODULE_FIRMWARE("radeon/HAINAN_pfp.bin");
MODULE_FIRMWARE("radeon/HAINAN_me.bin");
MODULE_FIRMWARE("radeon/HAINAN_ce.bin");
MODULE_FIRMWARE("radeon/HAINAN_mc.bin");
+MODULE_FIRMWARE("radeon/HAINAN_mc2.bin");
MODULE_FIRMWARE("radeon/HAINAN_rlc.bin");
MODULE_FIRMWARE("radeon/HAINAN_smc.bin");
const __be32 *fw_data;
u32 running, blackout = 0;
u32 *io_mc_regs;
- int i, ucode_size, regs_size;
+ int i, regs_size, ucode_size;
if (!rdev->mc_fw)
return -EINVAL;
+ ucode_size = rdev->mc_fw->size / 4;
+
switch (rdev->family) {
case CHIP_TAHITI:
io_mc_regs = (u32 *)&tahiti_io_mc_regs;
- ucode_size = SI_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE;
break;
case CHIP_PITCAIRN:
io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
- ucode_size = SI_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE;
break;
case CHIP_VERDE:
default:
io_mc_regs = (u32 *)&verde_io_mc_regs;
- ucode_size = SI_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE;
break;
case CHIP_OLAND:
io_mc_regs = (u32 *)&oland_io_mc_regs;
- ucode_size = OLAND_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE;
break;
case CHIP_HAINAN:
io_mc_regs = (u32 *)&hainan_io_mc_regs;
- ucode_size = OLAND_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE;
break;
}
const char *chip_name;
const char *rlc_chip_name;
size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size;
- size_t smc_req_size;
+ size_t smc_req_size, mc2_req_size;
char fw_name[30];
int err;
ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4;
mc_req_size = SI_MC_UCODE_SIZE * 4;
+ mc2_req_size = TAHITI_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4);
break;
case CHIP_PITCAIRN:
ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4;
mc_req_size = SI_MC_UCODE_SIZE * 4;
+ mc2_req_size = PITCAIRN_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4);
break;
case CHIP_VERDE:
ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4;
mc_req_size = SI_MC_UCODE_SIZE * 4;
+ mc2_req_size = VERDE_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4);
break;
case CHIP_OLAND:
me_req_size = SI_PM4_UCODE_SIZE * 4;
ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4;
- mc_req_size = OLAND_MC_UCODE_SIZE * 4;
+ mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4);
break;
case CHIP_HAINAN:
me_req_size = SI_PM4_UCODE_SIZE * 4;
ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4;
- mc_req_size = OLAND_MC_UCODE_SIZE * 4;
+ mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4);
break;
default: BUG();
err = -EINVAL;
}
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
- if (err)
- goto out;
- if (rdev->mc_fw->size != mc_req_size) {
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+ err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ }
+ if ((rdev->mc_fw->size != mc_req_size) &&
+ (rdev->mc_fw->size != mc2_req_size)) {
printk(KERN_ERR
"si_mc: Bogus length %zu in firmware \"%s\"\n",
rdev->mc_fw->size, fw_name);
err = -EINVAL;
}
+ DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
struct drm_dp_aux_msg *msg)
{
- unsigned long value = DPAUX_DP_AUXCTL_TRANSACTREQ;
unsigned long timeout = msecs_to_jiffies(250);
struct tegra_dpaux *dpaux = to_dpaux(aux);
unsigned long status;
ssize_t ret = 0;
+ u32 value;
- if (msg->size < 1 || msg->size > 16)
+ /* Tegra has 4x4 byte DP AUX transmit and receive FIFOs. */
+ if (msg->size > 16)
return -EINVAL;
- tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR);
+ /*
+ * Allow zero-sized messages only for I2C, in which case they specify
+ * address-only transactions.
+ */
+ if (msg->size < 1) {
+ switch (msg->request & ~DP_AUX_I2C_MOT) {
+ case DP_AUX_I2C_WRITE:
+ case DP_AUX_I2C_READ:
+ value = DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ } else {
+ /* For non-zero-sized messages, set the CMDLEN field. */
+ value = DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1);
+ }
switch (msg->request & ~DP_AUX_I2C_MOT) {
case DP_AUX_I2C_WRITE:
if (msg->request & DP_AUX_I2C_MOT)
- value = DPAUX_DP_AUXCTL_CMD_MOT_WR;
+ value |= DPAUX_DP_AUXCTL_CMD_MOT_WR;
else
- value = DPAUX_DP_AUXCTL_CMD_I2C_WR;
+ value |= DPAUX_DP_AUXCTL_CMD_I2C_WR;
break;
case DP_AUX_I2C_READ:
if (msg->request & DP_AUX_I2C_MOT)
- value = DPAUX_DP_AUXCTL_CMD_MOT_RD;
+ value |= DPAUX_DP_AUXCTL_CMD_MOT_RD;
else
- value = DPAUX_DP_AUXCTL_CMD_I2C_RD;
+ value |= DPAUX_DP_AUXCTL_CMD_I2C_RD;
break;
case DP_AUX_I2C_STATUS:
if (msg->request & DP_AUX_I2C_MOT)
- value = DPAUX_DP_AUXCTL_CMD_MOT_RQ;
+ value |= DPAUX_DP_AUXCTL_CMD_MOT_RQ;
else
- value = DPAUX_DP_AUXCTL_CMD_I2C_RQ;
+ value |= DPAUX_DP_AUXCTL_CMD_I2C_RQ;
break;
case DP_AUX_NATIVE_WRITE:
- value = DPAUX_DP_AUXCTL_CMD_AUX_WR;
+ value |= DPAUX_DP_AUXCTL_CMD_AUX_WR;
break;
case DP_AUX_NATIVE_READ:
- value = DPAUX_DP_AUXCTL_CMD_AUX_RD;
+ value |= DPAUX_DP_AUXCTL_CMD_AUX_RD;
break;
default:
return -EINVAL;
}
- value |= DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1);
+ tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR);
tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL);
if ((msg->request & DP_AUX_I2C_READ) == 0) {
break;
}
- if (msg->reply == DP_AUX_NATIVE_REPLY_ACK) {
+ if ((msg->size > 0) && (msg->reply == DP_AUX_NATIVE_REPLY_ACK)) {
if (msg->request & DP_AUX_I2C_READ) {
size_t count = value & DPAUX_DP_AUXSTAT_REPLY_MASK;
#define DPAUX_DP_AUXCTL_CMD_I2C_RQ (2 << 12)
#define DPAUX_DP_AUXCTL_CMD_I2C_RD (1 << 12)
#define DPAUX_DP_AUXCTL_CMD_I2C_WR (0 << 12)
+#define DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY (1 << 8)
#define DPAUX_DP_AUXCTL_CMDLEN(x) ((x) & 0xff)
#define DPAUX_DP_AUXSTAT 0x31
unsigned long reg;
int i, id;
- for (i = 0; i <= BIT_WORD(host->info->nb_pts); i++) {
+ for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) {
reg = host1x_sync_readl(host,
HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i));
for_each_set_bit(id, ®, BITS_PER_LONG) {
{
u32 i;
- for (i = 0; i <= BIT_WORD(host->info->nb_pts); ++i) {
+ for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); ++i) {
host1x_sync_writel(host, 0xffffffffu,
HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(i));
host1x_sync_writel(host, 0xffffffffu,
case HID_MAIN_ITEM_TAG_END_COLLECTION:
break;
case HID_MAIN_ITEM_TAG_INPUT:
+ /* ignore constant inputs, they will be ignored by hid-input */
+ if (data & HID_MAIN_ITEM_CONSTANT)
+ break;
for (i = 0; i < parser->local.usage_index; i++)
hid_scan_input_usage(parser, parser->local.usage[i]);
break;
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
#define USB_VENDOR_ID_INTEL_0 0x8086
#define USB_VENDOR_ID_INTEL_1 0x8087
-#define USB_DEVICE_ID_INTEL_HID_SENSOR 0x09fa
+#define USB_DEVICE_ID_INTEL_HID_SENSOR_0 0x09fa
+#define USB_DEVICE_ID_INTEL_HID_SENSOR_1 0x0a04
#define USB_VENDOR_ID_STM_0 0x0483
#define USB_DEVICE_ID_STM_HID_SENSOR 0x91d1
#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713
#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730
#define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c
-#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7
-#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9
#define USB_VENDOR_ID_MOJO 0x8282
#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
.driver_data = MS_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500),
.driver_data = MS_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2),
- .driver_data = 0 },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2),
- .driver_data = 0 },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
.driver_data = MS_PRESENTER },
static const struct hid_device_id sensor_hub_devices[] = {
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0,
- USB_DEVICE_ID_INTEL_HID_SENSOR),
+ USB_DEVICE_ID_INTEL_HID_SENSOR_0),
.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
- USB_DEVICE_ID_INTEL_HID_SENSOR),
+ USB_DEVICE_ID_INTEL_HID_SENSOR_0),
+ .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
+ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
+ USB_DEVICE_ID_INTEL_HID_SENSOR_1),
.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0,
USB_DEVICE_ID_STM_HID_SENSOR),
if (sc->quirks & SONY_LED_SUPPORT)
sony_leds_remove(hdev);
- if (sc->worker_initialized)
- cancel_work_sync(&sc->state_worker);
if (sc->quirks & SONY_BATTERY_SUPPORT) {
hid_hw_close(hdev);
sony_battery_remove(sc);
case (VERSION_WIN8):
return VERSION_WIN7;
+ case (VERSION_WIN8_1):
+ return VERSION_WIN8;
+
case (VERSION_WS2008):
default:
return VERSION_INVAL;
msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
- if (version == VERSION_WIN8)
+ if (version == VERSION_WIN8_1)
msg->target_vcpu = hv_context.vp_index[smp_processor_id()];
/*
-/*
+ /*
* Driver for Linear Technology LTC2945 I2C Power Monitor
*
* Copyright (c) 2014 Guenter Roeck
reg = LTC2945_MAX_ADIN_H;
break;
default:
- BUG();
- break;
+ WARN_ONCE(1, "Bad register: 0x%x\n", reg);
+ return -EINVAL;
}
/* Reset maximum */
ret = regmap_bulk_write(regmap, reg, buf_max, num_regs);
struct vexpress_hwmon_data {
struct device *hwmon_dev;
struct vexpress_config_func *func;
+ const char *name;
};
static ssize_t vexpress_hwmon_name_show(struct device *dev,
struct device_attribute *dev_attr, char *buffer)
{
- const char *compatible = of_get_property(dev->of_node, "compatible",
- NULL);
+ struct vexpress_hwmon_data *data = dev_get_drvdata(dev);
- return sprintf(buffer, "%s\n", compatible);
+ return sprintf(buffer, "%s\n", data->name);
}
static ssize_t vexpress_hwmon_label_show(struct device *dev,
{
const char *label = of_get_property(dev->of_node, "label", NULL);
- if (!label)
- return -ENOENT;
-
return snprintf(buffer, PAGE_SIZE, "%s\n", label);
}
to_sensor_dev_attr(dev_attr)->index));
}
+static umode_t vexpress_hwmon_attr_is_visible(struct kobject *kobj,
+ struct attribute *attr, int index)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ struct device_attribute *dev_attr = container_of(attr,
+ struct device_attribute, attr);
+
+ if (dev_attr->show == vexpress_hwmon_label_show &&
+ !of_get_property(dev->of_node, "label", NULL))
+ return 0;
+
+ return attr->mode;
+}
+
static DEVICE_ATTR(name, S_IRUGO, vexpress_hwmon_name_show, NULL);
#define VEXPRESS_HWMON_ATTRS(_name, _label_attr, _input_attr) \
NULL \
}
+struct vexpress_hwmon_type {
+ const char *name;
+ const struct attribute_group **attr_groups;
+};
+
#if !defined(CONFIG_REGULATOR_VEXPRESS)
static DEVICE_ATTR(in1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, vexpress_hwmon_u32_show,
NULL, 1000);
static VEXPRESS_HWMON_ATTRS(volt, in1_label, in1_input);
static struct attribute_group vexpress_hwmon_group_volt = {
+ .is_visible = vexpress_hwmon_attr_is_visible,
.attrs = vexpress_hwmon_attrs_volt,
};
+static struct vexpress_hwmon_type vexpress_hwmon_volt = {
+ .name = "vexpress_volt",
+ .attr_groups = (const struct attribute_group *[]) {
+ &vexpress_hwmon_group_volt,
+ NULL,
+ },
+};
#endif
static DEVICE_ATTR(curr1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
NULL, 1000);
static VEXPRESS_HWMON_ATTRS(amp, curr1_label, curr1_input);
static struct attribute_group vexpress_hwmon_group_amp = {
+ .is_visible = vexpress_hwmon_attr_is_visible,
.attrs = vexpress_hwmon_attrs_amp,
};
+static struct vexpress_hwmon_type vexpress_hwmon_amp = {
+ .name = "vexpress_amp",
+ .attr_groups = (const struct attribute_group *[]) {
+ &vexpress_hwmon_group_amp,
+ NULL
+ },
+};
static DEVICE_ATTR(temp1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, vexpress_hwmon_u32_show,
NULL, 1000);
static VEXPRESS_HWMON_ATTRS(temp, temp1_label, temp1_input);
static struct attribute_group vexpress_hwmon_group_temp = {
+ .is_visible = vexpress_hwmon_attr_is_visible,
.attrs = vexpress_hwmon_attrs_temp,
};
+static struct vexpress_hwmon_type vexpress_hwmon_temp = {
+ .name = "vexpress_temp",
+ .attr_groups = (const struct attribute_group *[]) {
+ &vexpress_hwmon_group_temp,
+ NULL
+ },
+};
static DEVICE_ATTR(power1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, vexpress_hwmon_u32_show,
NULL, 1);
static VEXPRESS_HWMON_ATTRS(power, power1_label, power1_input);
static struct attribute_group vexpress_hwmon_group_power = {
+ .is_visible = vexpress_hwmon_attr_is_visible,
.attrs = vexpress_hwmon_attrs_power,
};
+static struct vexpress_hwmon_type vexpress_hwmon_power = {
+ .name = "vexpress_power",
+ .attr_groups = (const struct attribute_group *[]) {
+ &vexpress_hwmon_group_power,
+ NULL
+ },
+};
static DEVICE_ATTR(energy1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
static SENSOR_DEVICE_ATTR(energy1_input, S_IRUGO, vexpress_hwmon_u64_show,
NULL, 1);
static VEXPRESS_HWMON_ATTRS(energy, energy1_label, energy1_input);
static struct attribute_group vexpress_hwmon_group_energy = {
+ .is_visible = vexpress_hwmon_attr_is_visible,
.attrs = vexpress_hwmon_attrs_energy,
};
+static struct vexpress_hwmon_type vexpress_hwmon_energy = {
+ .name = "vexpress_energy",
+ .attr_groups = (const struct attribute_group *[]) {
+ &vexpress_hwmon_group_energy,
+ NULL
+ },
+};
static struct of_device_id vexpress_hwmon_of_match[] = {
#if !defined(CONFIG_REGULATOR_VEXPRESS)
{
.compatible = "arm,vexpress-volt",
- .data = &vexpress_hwmon_group_volt,
+ .data = &vexpress_hwmon_volt,
},
#endif
{
.compatible = "arm,vexpress-amp",
- .data = &vexpress_hwmon_group_amp,
+ .data = &vexpress_hwmon_amp,
}, {
.compatible = "arm,vexpress-temp",
- .data = &vexpress_hwmon_group_temp,
+ .data = &vexpress_hwmon_temp,
}, {
.compatible = "arm,vexpress-power",
- .data = &vexpress_hwmon_group_power,
+ .data = &vexpress_hwmon_power,
}, {
.compatible = "arm,vexpress-energy",
- .data = &vexpress_hwmon_group_energy,
+ .data = &vexpress_hwmon_energy,
},
{}
};
int err;
const struct of_device_id *match;
struct vexpress_hwmon_data *data;
+ const struct vexpress_hwmon_type *type;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
match = of_match_device(vexpress_hwmon_of_match, &pdev->dev);
if (!match)
return -ENODEV;
+ type = match->data;
+ data->name = type->name;
data->func = vexpress_config_func_get_by_dev(&pdev->dev);
if (!data->func)
return -ENODEV;
- err = sysfs_create_group(&pdev->dev.kobj, match->data);
+ err = sysfs_create_groups(&pdev->dev.kobj, type->attr_groups);
if (err)
goto error;
if (package_num + 1 > num_sockets) {
num_sockets = package_num + 1;
- if (num_sockets > 4)
+ if (num_sockets > 4) {
cpuidle_state_table = ivt_cstates_8s;
return;
+ }
}
}
source "drivers/iio/trigger/Kconfig"
endif #IIO_TRIGGER
source "drivers/iio/pressure/Kconfig"
+source "drivers/iio/proximity/Kconfig"
source "drivers/iio/temperature/Kconfig"
endif # IIO
obj-y += magnetometer/
obj-y += orientation/
obj-y += pressure/
+obj-y += proximity/
obj-y += temperature/
obj-y += trigger/
Say yes here to build support for the Kionix KXSD9 accelerometer.
Currently this only supports the device via an SPI interface.
+config MMA8452
+ tristate "Freescale MMA8452Q Accelerometer Driver"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for the Freescale MMA8452Q 3-axis
+ accelerometer.
+
+ To compile this driver as a module, choose M here: the module
+ will be called mma8452.
+
endmenu
obj-$(CONFIG_BMA180) += bma180.o
obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
obj-$(CONFIG_KXSD9) += kxsd9.o
+obj-$(CONFIG_MMA8452) += mma8452.o
obj-$(CONFIG_IIO_ST_ACCEL_3AXIS) += st_accel.o
st_accel-y := st_accel_core.o
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
+#include <linux/delay.h>
#include <linux/hid-sensor-hub.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info accel[ACCEL_3D_CHANNEL_MAX];
u32 accel_val[ACCEL_3D_CHANNEL_MAX];
+ int scale_pre_decml;
+ int scale_post_decml;
+ int scale_precision;
+ int value_offset;
};
static const u32 accel_3d_addresses[ACCEL_3D_CHANNEL_MAX] = {
.type = IIO_ACCEL,
.modified = 1,
.channel2 = IIO_MOD_X,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
.type = IIO_ACCEL,
.modified = 1,
.channel2 = IIO_MOD_Y,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
.type = IIO_ACCEL,
.modified = 1,
.channel2 = IIO_MOD_Z,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
u32 address;
int ret;
int ret_type;
+ s32 poll_value;
*val = 0;
*val2 = 0;
switch (mask) {
case 0:
+ poll_value = hid_sensor_read_poll_value(
+ &accel_state->common_attributes);
+ if (poll_value < 0)
+ return -EINVAL;
+
+ hid_sensor_power_state(&accel_state->common_attributes, true);
+ msleep_interruptible(poll_value * 2);
report_id = accel_state->accel[chan->scan_index].report_id;
address = accel_3d_addresses[chan->scan_index];
if (report_id >= 0)
*val = sensor_hub_input_attr_get_raw_value(
- accel_state->common_attributes.hsdev,
- HID_USAGE_SENSOR_ACCEL_3D, address,
- report_id);
+ accel_state->common_attributes.hsdev,
+ HID_USAGE_SENSOR_ACCEL_3D, address,
+ report_id);
else {
*val = 0;
+ hid_sensor_power_state(&accel_state->common_attributes,
+ false);
return -EINVAL;
}
+ hid_sensor_power_state(&accel_state->common_attributes, false);
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
- *val = accel_state->accel[CHANNEL_SCAN_INDEX_X].units;
- ret_type = IIO_VAL_INT;
+ *val = accel_state->scale_pre_decml;
+ *val2 = accel_state->scale_post_decml;
+ ret_type = accel_state->scale_precision;
break;
case IIO_CHAN_INFO_OFFSET:
- *val = hid_sensor_convert_exponent(
- accel_state->accel[CHANNEL_SCAN_INDEX_X].unit_expo);
+ *val = accel_state->value_offset;
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct accel_3d_state *accel_state = iio_priv(indio_dev);
- dev_dbg(&indio_dev->dev, "accel_3d_proc_event [%d]\n",
- accel_state->common_attributes.data_ready);
- if (accel_state->common_attributes.data_ready)
+ dev_dbg(&indio_dev->dev, "accel_3d_proc_event\n");
+ if (atomic_read(&accel_state->common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
accel_state->accel_val,
sizeof(accel_state->accel_val));
st->accel[1].index, st->accel[1].report_id,
st->accel[2].index, st->accel[2].report_id);
+ st->scale_precision = hid_sensor_format_scale(
+ HID_USAGE_SENSOR_ACCEL_3D,
+ &st->accel[CHANNEL_SCAN_INDEX_X],
+ &st->scale_pre_decml, &st->scale_post_decml);
+
/* Set Sensitivity field ids, when there is no individual modifier */
if (st->common_attributes.sensitivity.index < 0) {
sensor_hub_input_get_attribute_info(hsdev,
dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
goto error_free_dev_mem;
}
- accel_state->common_attributes.data_ready = false;
+ atomic_set(&accel_state->common_attributes.data_ready, 0);
ret = hid_sensor_setup_trigger(indio_dev, name,
&accel_state->common_attributes);
if (ret < 0) {
--- /dev/null
+/*
+ * mma8452.c - Support for Freescale MMA8452Q 3-axis 12-bit accelerometer
+ *
+ * Copyright 2014 Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * 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.
+ *
+ * 7-bit I2C slave address 0x1c/0x1d (pin selectable)
+ *
+ * TODO: interrupt, thresholding, orientation / freefall events, autosleep
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/delay.h>
+
+#define MMA8452_STATUS 0x00
+#define MMA8452_OUT_X 0x01 /* MSB first, 12-bit */
+#define MMA8452_OUT_Y 0x03
+#define MMA8452_OUT_Z 0x05
+#define MMA8452_WHO_AM_I 0x0d
+#define MMA8452_DATA_CFG 0x0e
+#define MMA8452_OFF_X 0x2f
+#define MMA8452_OFF_Y 0x30
+#define MMA8452_OFF_Z 0x31
+#define MMA8452_CTRL_REG1 0x2a
+#define MMA8452_CTRL_REG2 0x2b
+
+#define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0))
+
+#define MMA8452_CTRL_DR_MASK (BIT(5) | BIT(4) | BIT(3))
+#define MMA8452_CTRL_DR_SHIFT 3
+#define MMA8452_CTRL_DR_DEFAULT 0x4 /* 50 Hz sample frequency */
+#define MMA8452_CTRL_ACTIVE BIT(0)
+
+#define MMA8452_DATA_CFG_FS_MASK (BIT(1) | BIT(0))
+#define MMA8452_DATA_CFG_FS_2G 0
+#define MMA8452_DATA_CFG_FS_4G 1
+#define MMA8452_DATA_CFG_FS_8G 2
+
+#define MMA8452_DEVICE_ID 0x2a
+
+struct mma8452_data {
+ struct i2c_client *client;
+ struct mutex lock;
+ u8 ctrl_reg1;
+ u8 data_cfg;
+};
+
+static int mma8452_drdy(struct mma8452_data *data)
+{
+ int tries = 150;
+
+ while (tries-- > 0) {
+ int ret = i2c_smbus_read_byte_data(data->client,
+ MMA8452_STATUS);
+ if (ret < 0)
+ return ret;
+ if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY)
+ return 0;
+ msleep(20);
+ }
+
+ dev_err(&data->client->dev, "data not ready\n");
+ return -EIO;
+}
+
+static int mma8452_read(struct mma8452_data *data, __be16 buf[3])
+{
+ int ret = mma8452_drdy(data);
+ if (ret < 0)
+ return ret;
+ return i2c_smbus_read_i2c_block_data(data->client,
+ MMA8452_OUT_X, 3 * sizeof(__be16), (u8 *) buf);
+}
+
+static ssize_t mma8452_show_int_plus_micros(char *buf,
+ const int (*vals)[2], int n)
+{
+ size_t len = 0;
+
+ while (n-- > 0)
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "%d.%06d ", vals[n][0], vals[n][1]);
+
+ /* replace trailing space by newline */
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n,
+ int val, int val2)
+{
+ while (n-- > 0)
+ if (val == vals[n][0] && val2 == vals[n][1])
+ return n;
+
+ return -EINVAL;
+}
+
+static const int mma8452_samp_freq[8][2] = {
+ {800, 0}, {400, 0}, {200, 0}, {100, 0}, {50, 0}, {12, 500000},
+ {6, 250000}, {1, 560000}
+};
+
+static const int mma8452_scales[3][2] = {
+ {0, 977}, {0, 1953}, {0, 3906}
+};
+
+static ssize_t mma8452_show_samp_freq_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return mma8452_show_int_plus_micros(buf, mma8452_samp_freq,
+ ARRAY_SIZE(mma8452_samp_freq));
+}
+
+static ssize_t mma8452_show_scale_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return mma8452_show_int_plus_micros(buf, mma8452_scales,
+ ARRAY_SIZE(mma8452_scales));
+}
+
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(mma8452_show_samp_freq_avail);
+static IIO_DEVICE_ATTR(in_accel_scale_available, S_IRUGO,
+ mma8452_show_scale_avail, NULL, 0);
+
+static int mma8452_get_samp_freq_index(struct mma8452_data *data,
+ int val, int val2)
+{
+ return mma8452_get_int_plus_micros_index(mma8452_samp_freq,
+ ARRAY_SIZE(mma8452_samp_freq), val, val2);
+}
+
+static int mma8452_get_scale_index(struct mma8452_data *data,
+ int val, int val2)
+{
+ return mma8452_get_int_plus_micros_index(mma8452_scales,
+ ARRAY_SIZE(mma8452_scales), val, val2);
+}
+
+static int mma8452_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct mma8452_data *data = iio_priv(indio_dev);
+ __be16 buffer[3];
+ int i, ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (iio_buffer_enabled(indio_dev))
+ return -EBUSY;
+
+ mutex_lock(&data->lock);
+ ret = mma8452_read(data, buffer);
+ mutex_unlock(&data->lock);
+ if (ret < 0)
+ return ret;
+ *val = sign_extend32(
+ be16_to_cpu(buffer[chan->scan_index]) >> 4, 11);
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK;
+ *val = mma8452_scales[i][0];
+ *val2 = mma8452_scales[i][1];
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ i = (data->ctrl_reg1 & MMA8452_CTRL_DR_MASK) >>
+ MMA8452_CTRL_DR_SHIFT;
+ *val = mma8452_samp_freq[i][0];
+ *val2 = mma8452_samp_freq[i][1];
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_CALIBBIAS:
+ ret = i2c_smbus_read_byte_data(data->client, MMA8452_OFF_X +
+ chan->scan_index);
+ if (ret < 0)
+ return ret;
+ *val = sign_extend32(ret, 7);
+ return IIO_VAL_INT;
+ }
+ return -EINVAL;
+}
+
+static int mma8452_standby(struct mma8452_data *data)
+{
+ return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
+ data->ctrl_reg1 & ~MMA8452_CTRL_ACTIVE);
+}
+
+static int mma8452_active(struct mma8452_data *data)
+{
+ return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
+ data->ctrl_reg1);
+}
+
+static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val)
+{
+ int ret;
+
+ mutex_lock(&data->lock);
+
+ /* config can only be changed when in standby */
+ ret = mma8452_standby(data);
+ if (ret < 0)
+ goto fail;
+
+ ret = i2c_smbus_write_byte_data(data->client, reg, val);
+ if (ret < 0)
+ goto fail;
+
+ ret = mma8452_active(data);
+ if (ret < 0)
+ goto fail;
+
+ ret = 0;
+fail:
+ mutex_unlock(&data->lock);
+ return ret;
+}
+
+static int mma8452_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct mma8452_data *data = iio_priv(indio_dev);
+ int i;
+
+ if (iio_buffer_enabled(indio_dev))
+ return -EBUSY;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ i = mma8452_get_samp_freq_index(data, val, val2);
+ if (i < 0)
+ return -EINVAL;
+
+ data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK;
+ data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT;
+ return mma8452_change_config(data, MMA8452_CTRL_REG1,
+ data->ctrl_reg1);
+ case IIO_CHAN_INFO_SCALE:
+ i = mma8452_get_scale_index(data, val, val2);
+ if (i < 0)
+ return -EINVAL;
+ data->data_cfg &= ~MMA8452_DATA_CFG_FS_MASK;
+ data->data_cfg |= i;
+ return mma8452_change_config(data, MMA8452_DATA_CFG,
+ data->data_cfg);
+ case IIO_CHAN_INFO_CALIBBIAS:
+ if (val < -128 || val > 127)
+ return -EINVAL;
+ return mma8452_change_config(data, MMA8452_OFF_X +
+ chan->scan_index, val);
+ default:
+ return -EINVAL;
+ }
+}
+
+static irqreturn_t mma8452_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct mma8452_data *data = iio_priv(indio_dev);
+ u8 buffer[16]; /* 3 16-bit channels + padding + ts */
+ int ret;
+
+ ret = mma8452_read(data, (__be16 *) buffer);
+ if (ret < 0)
+ goto done;
+
+ iio_push_to_buffers_with_timestamp(indio_dev, buffer,
+ iio_get_time_ns());
+
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+ return IRQ_HANDLED;
+}
+
+#define MMA8452_CHANNEL(axis, idx) { \
+ .type = IIO_ACCEL, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_CALIBBIAS), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .scan_index = idx, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 12, \
+ .storagebits = 16, \
+ .shift = 4, \
+ .endianness = IIO_BE, \
+ }, \
+}
+
+static const struct iio_chan_spec mma8452_channels[] = {
+ MMA8452_CHANNEL(X, 0),
+ MMA8452_CHANNEL(Y, 1),
+ MMA8452_CHANNEL(Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static struct attribute *mma8452_attributes[] = {
+ &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group mma8452_group = {
+ .attrs = mma8452_attributes,
+};
+
+static const struct iio_info mma8452_info = {
+ .attrs = &mma8452_group,
+ .read_raw = &mma8452_read_raw,
+ .write_raw = &mma8452_write_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static const unsigned long mma8452_scan_masks[] = {0x7, 0};
+
+static int mma8452_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct mma8452_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(client, MMA8452_WHO_AM_I);
+ if (ret < 0)
+ return ret;
+ if (ret != MMA8452_DEVICE_ID)
+ return -ENODEV;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ data->client = client;
+ mutex_init(&data->lock);
+
+ i2c_set_clientdata(client, indio_dev);
+ indio_dev->info = &mma8452_info;
+ indio_dev->name = id->name;
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = mma8452_channels;
+ indio_dev->num_channels = ARRAY_SIZE(mma8452_channels);
+ indio_dev->available_scan_masks = mma8452_scan_masks;
+
+ data->ctrl_reg1 = MMA8452_CTRL_ACTIVE |
+ (MMA8452_CTRL_DR_DEFAULT << MMA8452_CTRL_DR_SHIFT);
+ ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG1,
+ data->ctrl_reg1);
+ if (ret < 0)
+ return ret;
+
+ data->data_cfg = MMA8452_DATA_CFG_FS_2G;
+ ret = i2c_smbus_write_byte_data(client, MMA8452_DATA_CFG,
+ data->data_cfg);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ mma8452_trigger_handler, NULL);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0)
+ goto buffer_cleanup;
+ return 0;
+
+buffer_cleanup:
+ iio_triggered_buffer_cleanup(indio_dev);
+ return ret;
+}
+
+static int mma8452_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+ mma8452_standby(iio_priv(indio_dev));
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mma8452_suspend(struct device *dev)
+{
+ return mma8452_standby(iio_priv(i2c_get_clientdata(
+ to_i2c_client(dev))));
+}
+
+static int mma8452_resume(struct device *dev)
+{
+ return mma8452_active(iio_priv(i2c_get_clientdata(
+ to_i2c_client(dev))));
+}
+
+static SIMPLE_DEV_PM_OPS(mma8452_pm_ops, mma8452_suspend, mma8452_resume);
+#define MMA8452_PM_OPS (&mma8452_pm_ops)
+#else
+#define MMA8452_PM_OPS NULL
+#endif
+
+static const struct i2c_device_id mma8452_id[] = {
+ { "mma8452", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, mma8452_id);
+
+static struct i2c_driver mma8452_driver = {
+ .driver = {
+ .name = "mma8452",
+ .pm = MMA8452_PM_OPS,
+ },
+ .probe = mma8452_probe,
+ .remove = mma8452_remove,
+ .id_table = mma8452_id,
+};
+module_i2c_driver(mma8452_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("Freescale MMA8452 accelerometer driver");
+MODULE_LICENSE("GPL");
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &accel_info;
+ st_sensors_power_enable(indio_dev);
+
err = st_sensors_check_device_support(indio_dev,
ARRAY_SIZE(st_accel_sensors), st_accel_sensors);
if (err < 0)
if (err)
goto st_accel_device_register_error;
+ dev_info(&indio_dev->dev, "registered accelerometer %s\n",
+ indio_dev->name);
+
return 0;
st_accel_device_register_error:
{
struct st_sensor_data *adata = iio_priv(indio_dev);
+ st_sensors_power_disable(indio_dev);
+
iio_device_unregister(indio_dev);
if (adata->get_irq_data_ready(indio_dev) > 0)
st_sensors_deallocate_trigger(indio_dev);
To compile this driver as a module, choose M here: the
module will be called ad7923.
+config AD799X
+ tristate "Analog Devices AD799x ADC driver"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for Analog Devices:
+ ad7991, ad7995, ad7999, ad7992, ad7993, ad7994, ad7997, ad7998
+ i2c analog to digital converters (ADC). Provides direct access
+ via sysfs.
+
config AT91_ADC
tristate "Atmel AT91 ADC"
depends on ARCH_AT91
config EXYNOS_ADC
bool "Exynos ADC driver support"
- depends on OF
+ depends on ARCH_EXYNOS || (OF && COMPILE_TEST)
help
Core support for the ADC block found in the Samsung EXYNOS series
of SoCs for drivers such as the touchscreen and hwmon to use to share
called mcp320x.
config MCP3422
- tristate "Microchip Technology MCP3422/3/4 driver"
+ tristate "Microchip Technology MCP3422/3/4/6/7/8 driver"
depends on I2C
help
- Say yes here to build support for Microchip Technology's MCP3422,
- MCP3423 or MCP3424 analog to digital converters.
+ Say yes here to build support for Microchip Technology's
+ MCP3422, MCP3423, MCP3424, MCP3426, MCP3427 or MCP3428
+ analog to digital converters.
This driver can also be built as a module. If so, the module will be
called mcp3422.
obj-$(CONFIG_AD7791) += ad7791.o
obj-$(CONFIG_AD7793) += ad7793.o
obj-$(CONFIG_AD7887) += ad7887.o
+obj-$(CONFIG_AD799X) += ad799x.o
obj-$(CONFIG_AT91_ADC) += at91_adc.o
obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
#include <linux/iio/sysfs.h>
#include <linux/iio/events.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
-#include "ad799x.h"
+#define AD799X_CHANNEL_SHIFT 4
+#define AD799X_STORAGEBITS 16
+/*
+ * AD7991, AD7995 and AD7999 defines
+ */
+
+#define AD7991_REF_SEL 0x08
+#define AD7991_FLTR 0x04
+#define AD7991_BIT_TRIAL_DELAY 0x02
+#define AD7991_SAMPLE_DELAY 0x01
+
+/*
+ * AD7992, AD7993, AD7994, AD7997 and AD7998 defines
+ */
+
+#define AD7998_FLTR 0x08
+#define AD7998_ALERT_EN 0x04
+#define AD7998_BUSY_ALERT 0x02
+#define AD7998_BUSY_ALERT_POL 0x01
+
+#define AD7998_CONV_RES_REG 0x0
+#define AD7998_ALERT_STAT_REG 0x1
+#define AD7998_CONF_REG 0x2
+#define AD7998_CYCLE_TMR_REG 0x3
+
+#define AD7998_DATALOW_REG(x) ((x) * 3 + 0x4)
+#define AD7998_DATAHIGH_REG(x) ((x) * 3 + 0x5)
+#define AD7998_HYST_REG(x) ((x) * 3 + 0x6)
+
+#define AD7998_CYC_MASK 0x7
+#define AD7998_CYC_DIS 0x0
+#define AD7998_CYC_TCONF_32 0x1
+#define AD7998_CYC_TCONF_64 0x2
+#define AD7998_CYC_TCONF_128 0x3
+#define AD7998_CYC_TCONF_256 0x4
+#define AD7998_CYC_TCONF_512 0x5
+#define AD7998_CYC_TCONF_1024 0x6
+#define AD7998_CYC_TCONF_2048 0x7
+
+#define AD7998_ALERT_STAT_CLEAR 0xFF
+
+/*
+ * AD7997 and AD7997 defines
+ */
+
+#define AD7997_8_READ_SINGLE 0x80
+#define AD7997_8_READ_SEQUENCE 0x70
+/* TODO: move this into a common header */
+#define RES_MASK(bits) ((1 << (bits)) - 1)
+
+enum {
+ ad7991,
+ ad7995,
+ ad7999,
+ ad7992,
+ ad7993,
+ ad7994,
+ ad7997,
+ ad7998
+};
+
+/**
+ * struct ad799x_chip_info - chip specific information
+ * @channel: channel specification
+ * @num_channels: number of channels
+ * @monitor_mode: whether the chip supports monitor interrupts
+ * @default_config: device default configuration
+ * @event_attrs: pointer to the monitor event attribute group
+ */
+struct ad799x_chip_info {
+ struct iio_chan_spec channel[9];
+ int num_channels;
+ u16 default_config;
+ const struct iio_info *info;
+};
+
+struct ad799x_state {
+ struct i2c_client *client;
+ const struct ad799x_chip_info *chip_info;
+ struct regulator *reg;
+ struct regulator *vref;
+ unsigned id;
+ u16 config;
+
+ u8 *rx_buf;
+ unsigned int transfer_size;
+};
+
+/**
+ * ad799x_trigger_handler() bh of trigger launched polling to ring buffer
+ *
+ * Currently there is no option in this driver to disable the saving of
+ * timestamps within the ring.
+ **/
+static irqreturn_t ad799x_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct ad799x_state *st = iio_priv(indio_dev);
+ int b_sent;
+ u8 cmd;
+
+ switch (st->id) {
+ case ad7991:
+ case ad7995:
+ case ad7999:
+ cmd = st->config |
+ (*indio_dev->active_scan_mask << AD799X_CHANNEL_SHIFT);
+ break;
+ case ad7992:
+ case ad7993:
+ case ad7994:
+ cmd = (*indio_dev->active_scan_mask << AD799X_CHANNEL_SHIFT) |
+ AD7998_CONV_RES_REG;
+ break;
+ case ad7997:
+ case ad7998:
+ cmd = AD7997_8_READ_SEQUENCE | AD7998_CONV_RES_REG;
+ break;
+ default:
+ cmd = 0;
+ }
+
+ b_sent = i2c_smbus_read_i2c_block_data(st->client,
+ cmd, st->transfer_size, st->rx_buf);
+ if (b_sent < 0)
+ goto out;
+
+ iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
+ iio_get_time_ns());
+out:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
/*
* ad799x register access by I2C
indio_dev->channels = st->chip_info->channel;
indio_dev->num_channels = st->chip_info->num_channels;
- ret = ad799x_register_ring_funcs_and_init(indio_dev);
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ &ad799x_trigger_handler, NULL);
if (ret)
- goto error_disable_reg;
+ goto error_disable_vref;
if (client->irq > 0) {
ret = devm_request_threaded_irq(&client->dev,
return 0;
error_cleanup_ring:
- ad799x_ring_cleanup(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+error_disable_vref:
+ regulator_disable(st->vref);
error_disable_reg:
- if (!IS_ERR(st->vref))
- regulator_disable(st->vref);
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
+ regulator_disable(st->reg);
return ret;
}
iio_device_unregister(indio_dev);
- ad799x_ring_cleanup(indio_dev);
- if (!IS_ERR(st->vref))
- regulator_disable(st->vref);
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
+ iio_triggered_buffer_cleanup(indio_dev);
+ regulator_disable(st->vref);
+ regulator_disable(st->reg);
kfree(st->rx_buf);
return 0;
if (!pdata)
return -EINVAL;
+ st->caps = (struct at91_adc_caps *)
+ platform_get_device_id(pdev)->driver_data;
+
st->use_external = pdata->use_external_triggers;
st->vref_mv = pdata->vref;
st->channels_mask = pdata->channels_used;
- st->num_channels = pdata->num_channels;
+ st->num_channels = st->caps->num_channels;
st->startup_time = pdata->startup_time;
st->trigger_number = pdata->trigger_number;
st->trigger_list = pdata->trigger_list;
- st->registers = pdata->registers;
+ st->registers = &st->caps->registers;
return 0;
}
* the best converted final value between two channels selection
* The formula thus is : Sample and Hold Time = (shtim + 1) / ADCClock
*/
- shtim = round_up((st->sample_hold_time * adc_clk_khz /
- 1000) - 1, 1);
+ if (st->sample_hold_time > 0)
+ shtim = round_up((st->sample_hold_time * adc_clk_khz / 1000)
+ - 1, 1);
+ else
+ shtim = 0;
reg = AT91_ADC_PRESCAL_(prsc) & st->registers->mr_prescal_mask;
reg |= AT91_ADC_STARTUP_(ticks) & st->registers->mr_startup_mask;
return 0;
}
-#ifdef CONFIG_OF
static struct at91_adc_caps at91sam9260_caps = {
.calc_startup_ticks = calc_startup_ticks_9260,
.num_channels = 4,
{},
};
MODULE_DEVICE_TABLE(of, at91_adc_dt_ids);
-#endif
+
+static const struct platform_device_id at91_adc_ids[] = {
+ {
+ .name = "at91sam9260-adc",
+ .driver_data = (unsigned long)&at91sam9260_caps,
+ }, {
+ .name = "at91sam9g45-adc",
+ .driver_data = (unsigned long)&at91sam9g45_caps,
+ }, {
+ .name = "at91sam9x5-adc",
+ .driver_data = (unsigned long)&at91sam9x5_caps,
+ }, {
+ /* terminator */
+ }
+};
+MODULE_DEVICE_TABLE(platform, at91_adc_ids);
static struct platform_driver at91_adc_driver = {
.probe = at91_adc_probe,
.remove = at91_adc_remove,
+ .id_table = at91_adc_ids,
.driver = {
.name = DRIVER_NAME,
.of_match_table = of_match_ptr(at91_adc_dt_ids),
#define ADC_CON_EN_START (1u << 0)
#define ADC_DATX_MASK 0xFFF
-#define EXYNOS_ADC_TIMEOUT (msecs_to_jiffies(1000))
+#define EXYNOS_ADC_TIMEOUT (msecs_to_jiffies(100))
struct exynos_adc {
void __iomem *regs;
return (unsigned int)match->data;
}
+static void exynos_adc_hw_init(struct exynos_adc *info)
+{
+ u32 con1, con2;
+
+ if (info->version == ADC_V2) {
+ con1 = ADC_V2_CON1_SOFT_RESET;
+ writel(con1, ADC_V2_CON1(info->regs));
+
+ con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL |
+ ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0);
+ writel(con2, ADC_V2_CON2(info->regs));
+
+ /* Enable interrupts */
+ writel(1, ADC_V2_INT_EN(info->regs));
+ } else {
+ /* set default prescaler values and Enable prescaler */
+ con1 = ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN;
+
+ /* Enable 12-bit ADC resolution */
+ con1 |= ADC_V1_CON_RES;
+ writel(con1, ADC_V1_CON(info->regs));
+ }
+}
+
static int exynos_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
struct exynos_adc *info = iio_priv(indio_dev);
unsigned long timeout;
u32 con1, con2;
+ int ret;
if (mask != IIO_CHAN_INFO_RAW)
return -EINVAL;
mutex_lock(&indio_dev->mlock);
+ reinit_completion(&info->completion);
/* Select the channel to be used and Trigger conversion */
if (info->version == ADC_V2) {
ADC_V1_CON(info->regs));
}
- timeout = wait_for_completion_interruptible_timeout
+ timeout = wait_for_completion_timeout
(&info->completion, EXYNOS_ADC_TIMEOUT);
- *val = info->value;
+ if (timeout == 0) {
+ dev_warn(&indio_dev->dev, "Conversion timed out! Resetting\n");
+ exynos_adc_hw_init(info);
+ ret = -ETIMEDOUT;
+ } else {
+ *val = info->value;
+ *val2 = 0;
+ ret = IIO_VAL_INT;
+ }
mutex_unlock(&indio_dev->mlock);
- if (timeout == 0)
- return -ETIMEDOUT;
-
- return IIO_VAL_INT;
+ return ret;
}
static irqreturn_t exynos_adc_isr(int irq, void *dev_id)
return 0;
}
-static void exynos_adc_hw_init(struct exynos_adc *info)
-{
- u32 con1, con2;
-
- if (info->version == ADC_V2) {
- con1 = ADC_V2_CON1_SOFT_RESET;
- writel(con1, ADC_V2_CON1(info->regs));
-
- con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL |
- ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0);
- writel(con2, ADC_V2_CON2(info->regs));
-
- /* Enable interrupts */
- writel(1, ADC_V2_INT_EN(info->regs));
- } else {
- /* set default prescaler values and Enable prescaler */
- con1 = ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN;
-
- /* Enable 12-bit ADC resolution */
- con1 |= ADC_V1_CON_RES;
- writel(con1, ADC_V1_CON(info->regs));
- }
-}
-
static int exynos_adc_probe(struct platform_device *pdev)
{
struct exynos_adc *info = NULL;
init_completion(&info->completion);
- ret = request_irq(info->irq, exynos_adc_isr,
- 0, dev_name(&pdev->dev), info);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed requesting irq, irq = %d\n",
- info->irq);
- return ret;
- }
-
- writel(1, info->enable_reg);
-
info->clk = devm_clk_get(&pdev->dev, "adc");
if (IS_ERR(info->clk)) {
dev_err(&pdev->dev, "failed getting clock, err = %ld\n",
PTR_ERR(info->clk));
- ret = PTR_ERR(info->clk);
- goto err_irq;
+ return PTR_ERR(info->clk);
}
info->vdd = devm_regulator_get(&pdev->dev, "vdd");
if (IS_ERR(info->vdd)) {
dev_err(&pdev->dev, "failed getting regulator, err = %ld\n",
PTR_ERR(info->vdd));
- ret = PTR_ERR(info->vdd);
- goto err_irq;
+ return PTR_ERR(info->vdd);
}
+ ret = regulator_enable(info->vdd);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(info->clk);
+ if (ret)
+ goto err_disable_reg;
+
+ writel(1, info->enable_reg);
+
info->version = exynos_adc_get_version(pdev);
platform_set_drvdata(pdev, indio_dev);
else
indio_dev->num_channels = MAX_ADC_V2_CHANNELS;
+ ret = request_irq(info->irq, exynos_adc_isr,
+ 0, dev_name(&pdev->dev), info);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed requesting irq, irq = %d\n",
+ info->irq);
+ goto err_disable_clk;
+ }
+
ret = iio_device_register(indio_dev);
if (ret)
goto err_irq;
- ret = regulator_enable(info->vdd);
- if (ret)
- goto err_iio_dev;
-
- clk_prepare_enable(info->clk);
-
exynos_adc_hw_init(info);
ret = of_platform_populate(np, exynos_adc_match, NULL, &pdev->dev);
err_of_populate:
device_for_each_child(&pdev->dev, NULL,
exynos_adc_remove_devices);
- regulator_disable(info->vdd);
- clk_disable_unprepare(info->clk);
-err_iio_dev:
iio_device_unregister(indio_dev);
err_irq:
free_irq(info->irq, info);
+err_disable_clk:
+ writel(0, info->enable_reg);
+ clk_disable_unprepare(info->clk);
+err_disable_reg:
+ regulator_disable(info->vdd);
return ret;
}
device_for_each_child(&pdev->dev, NULL,
exynos_adc_remove_devices);
- regulator_disable(info->vdd);
- clk_disable_unprepare(info->clk);
- writel(0, info->enable_reg);
iio_device_unregister(indio_dev);
free_irq(info->irq, info);
+ writel(0, info->enable_reg);
+ clk_disable_unprepare(info->clk);
+ regulator_disable(info->vdd);
return 0;
}
writel(con, ADC_V1_CON(info->regs));
}
- clk_disable_unprepare(info->clk);
writel(0, info->enable_reg);
+ clk_disable_unprepare(info->clk);
regulator_disable(info->vdd);
return 0;
if (ret)
return ret;
- writel(1, info->enable_reg);
- clk_prepare_enable(info->clk);
+ ret = clk_prepare_enable(info->clk);
+ if (ret)
+ return ret;
+ writel(1, info->enable_reg);
exynos_adc_hw_init(info);
return 0;
/*
- * mcp3422.c - driver for the Microchip mcp3422/3/4 chip family
+ * mcp3422.c - driver for the Microchip mcp3422/3/4/6/7/8 chip family
*
* Copyright (C) 2013, Angelo Compagnucci
* Author: Angelo Compagnucci <angelo.compagnucci@gmail.com>
*
* Datasheet: http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf
+ * http://ww1.microchip.com/downloads/en/DeviceDoc/22226a.pdf
*
* This driver exports the value of analog input voltage to sysfs, the
* voltage unit is nV.
/* Client data (each client gets its own) */
struct mcp3422 {
struct i2c_client *i2c;
+ u8 id;
u8 config;
u8 pga[4];
struct mutex lock;
temp = MCP3422_SRATE_15;
break;
case 3:
+ if (adc->id > 4)
+ return -EINVAL;
temp = MCP3422_SRATE_3;
break;
default:
}
}
+static ssize_t mcp3422_show_samp_freqs(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mcp3422 *adc = iio_priv(dev_to_iio_dev(dev));
+
+ if (adc->id > 4)
+ return sprintf(buf, "240 60 15\n");
+
+ return sprintf(buf, "240 60 15 3\n");
+}
+
static ssize_t mcp3422_show_scales(struct device *dev,
struct device_attribute *attr, char *buf)
{
mcp3422_scales[sample_rate][3]);
}
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("240 60 15 3");
+static IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO,
+ mcp3422_show_samp_freqs, NULL, 0);
static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO,
mcp3422_show_scales, NULL, 0);
static struct attribute *mcp3422_attributes[] = {
- &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
NULL,
};
adc = iio_priv(indio_dev);
adc->i2c = client;
+ adc->id = (u8)(id->driver_data);
mutex_init(&adc->lock);
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &mcp3422_info;
- switch ((unsigned int)(id->driver_data)) {
+ switch (adc->id) {
case 2:
case 3:
+ case 6:
+ case 7:
indio_dev->channels = mcp3422_channels;
indio_dev->num_channels = ARRAY_SIZE(mcp3422_channels);
break;
case 4:
+ case 8:
indio_dev->channels = mcp3424_channels;
indio_dev->num_channels = ARRAY_SIZE(mcp3424_channels);
break;
{ "mcp3422", 2 },
{ "mcp3423", 3 },
{ "mcp3424", 4 },
+ { "mcp3426", 6 },
+ { "mcp3427", 7 },
+ { "mcp3428", 8 },
{ }
};
MODULE_DEVICE_TABLE(i2c, mcp3422_id);
module_i2c_driver(mcp3422_driver);
MODULE_AUTHOR("Angelo Compagnucci <angelo.compagnucci@gmail.com>");
-MODULE_DESCRIPTION("Microchip mcp3422/3/4 driver");
+MODULE_DESCRIPTION("Microchip mcp3422/3/4/6/7/8 driver");
MODULE_LICENSE("GPL v2");
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+struct {
+ u32 usage_id;
+ int unit; /* 0 for default others from HID sensor spec */
+ int scale_val0; /* scale, whole number */
+ int scale_val1; /* scale, fraction in micros */
+} static unit_conversion[] = {
+ {HID_USAGE_SENSOR_ACCEL_3D, 0, 9, 806650},
+ {HID_USAGE_SENSOR_ACCEL_3D,
+ HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD, 1, 0},
+ {HID_USAGE_SENSOR_ACCEL_3D,
+ HID_USAGE_SENSOR_UNITS_G, 9, 806650},
+
+ {HID_USAGE_SENSOR_GYRO_3D, 0, 0, 17453},
+ {HID_USAGE_SENSOR_GYRO_3D,
+ HID_USAGE_SENSOR_UNITS_RADIANS_PER_SECOND, 1, 0},
+ {HID_USAGE_SENSOR_GYRO_3D,
+ HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, 0, 17453},
+
+ {HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000},
+ {HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_GAUSS, 1, 0},
+
+ {HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453},
+ {HID_USAGE_SENSOR_INCLINOMETER_3D,
+ HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453},
+ {HID_USAGE_SENSOR_INCLINOMETER_3D,
+ HID_USAGE_SENSOR_UNITS_RADIANS, 1, 0},
+
+ {HID_USAGE_SENSOR_ALS, 0, 1, 0},
+ {HID_USAGE_SENSOR_ALS, HID_USAGE_SENSOR_UNITS_LUX, 1, 0},
+
+ {HID_USAGE_SENSOR_PRESSURE, 0, 100000, 0},
+ {HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 1, 0},
+};
+
static int pow_10(unsigned power)
{
int i;
return value;
}
+s32 hid_sensor_read_poll_value(struct hid_sensor_common *st)
+{
+ s32 value = 0;
+ int ret;
+
+ ret = sensor_hub_get_feature(st->hsdev,
+ st->poll.report_id,
+ st->poll.index, &value);
+
+ if (ret < 0 || value < 0) {
+ return -EINVAL;
+ } else {
+ if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND)
+ value = value * 1000;
+ }
+
+ return value;
+}
+EXPORT_SYMBOL(hid_sensor_read_poll_value);
+
int hid_sensor_read_samp_freq_value(struct hid_sensor_common *st,
int *val1, int *val2)
{
}
EXPORT_SYMBOL(hid_sensor_write_raw_hyst_value);
+/*
+ * This fuction applies the unit exponent to the scale.
+ * For example:
+ * 9.806650 ->exp:2-> val0[980]val1[665000]
+ * 9.000806 ->exp:2-> val0[900]val1[80600]
+ * 0.174535 ->exp:2-> val0[17]val1[453500]
+ * 1.001745 ->exp:0-> val0[1]val1[1745]
+ * 1.001745 ->exp:2-> val0[100]val1[174500]
+ * 1.001745 ->exp:4-> val0[10017]val1[450000]
+ * 9.806650 ->exp:-2-> val0[0]val1[98066]
+ */
+static void adjust_exponent_micro(int *val0, int *val1, int scale0,
+ int scale1, int exp)
+{
+ int i;
+ int x;
+ int res;
+ int rem;
+
+ if (exp > 0) {
+ *val0 = scale0 * pow_10(exp);
+ res = 0;
+ if (exp > 6) {
+ *val1 = 0;
+ return;
+ }
+ for (i = 0; i < exp; ++i) {
+ x = scale1 / pow_10(5 - i);
+ res += (pow_10(exp - 1 - i) * x);
+ scale1 = scale1 % pow_10(5 - i);
+ }
+ *val0 += res;
+ *val1 = scale1 * pow_10(exp);
+ } else if (exp < 0) {
+ exp = abs(exp);
+ if (exp > 6) {
+ *val0 = *val1 = 0;
+ return;
+ }
+ *val0 = scale0 / pow_10(exp);
+ rem = scale0 % pow_10(exp);
+ res = 0;
+ for (i = 0; i < (6 - exp); ++i) {
+ x = scale1 / pow_10(5 - i);
+ res += (pow_10(5 - exp - i) * x);
+ scale1 = scale1 % pow_10(5 - i);
+ }
+ *val1 = rem * pow_10(6 - exp) + res;
+ } else {
+ *val0 = scale0;
+ *val1 = scale1;
+ }
+}
+
+int hid_sensor_format_scale(u32 usage_id,
+ struct hid_sensor_hub_attribute_info *attr_info,
+ int *val0, int *val1)
+{
+ int i;
+ int exp;
+
+ *val0 = 1;
+ *val1 = 0;
+
+ for (i = 0; ARRAY_SIZE(unit_conversion); ++i) {
+ if (unit_conversion[i].usage_id == usage_id &&
+ unit_conversion[i].unit == attr_info->units) {
+ exp = hid_sensor_convert_exponent(
+ attr_info->unit_expo);
+ adjust_exponent_micro(val0, val1,
+ unit_conversion[i].scale_val0,
+ unit_conversion[i].scale_val1, exp);
+ break;
+ }
+ }
+
+ return IIO_VAL_INT_PLUS_MICRO;
+}
+EXPORT_SYMBOL(hid_sensor_format_scale);
+
int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
u32 usage_id,
struct hid_sensor_common *st)
#include <linux/iio/sysfs.h>
#include "hid-sensor-trigger.h"
-static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
- bool state)
+int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
{
- struct hid_sensor_common *st = iio_trigger_get_drvdata(trig);
int state_val;
int report_val;
if (state) {
if (sensor_hub_device_open(st->hsdev))
return -EIO;
+
+ atomic_inc(&st->data_ready);
+
state_val = hid_sensor_get_usage_index(st->hsdev,
st->power_state.report_id,
st->power_state.index,
st->report_state.index,
HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM);
} else {
+ if (!atomic_dec_and_test(&st->data_ready))
+ return 0;
sensor_hub_device_close(st->hsdev);
state_val = hid_sensor_get_usage_index(st->hsdev,
st->power_state.report_id,
st->report_state.index,
HID_USAGE_SENSOR_PROP_REPORTING_STATE_NO_EVENTS_ENUM);
}
- st->data_ready = state;
if (state_val >= 0) {
state_val += st->power_state.logical_minimum;
return 0;
}
+EXPORT_SYMBOL(hid_sensor_power_state);
+
+static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
+ bool state)
+{
+ return hid_sensor_power_state(iio_trigger_get_drvdata(trig), state);
+}
void hid_sensor_remove_trigger(struct hid_sensor_common *attrb)
{
int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
struct hid_sensor_common *attrb);
void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
+int hid_sensor_power_state(struct hid_sensor_common *st, bool state);
#endif
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
+#include <linux/regulator/consumer.h>
#include <asm/unaligned.h>
#include <linux/iio/common/st_sensors.h>
}
EXPORT_SYMBOL(st_sensors_set_axis_enable);
+void st_sensors_power_enable(struct iio_dev *indio_dev)
+{
+ struct st_sensor_data *pdata = iio_priv(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");
+ }
+
+ 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");
+ }
+}
+EXPORT_SYMBOL(st_sensors_power_enable);
+
+void st_sensors_power_disable(struct iio_dev *indio_dev)
+{
+ struct st_sensor_data *pdata = iio_priv(indio_dev);
+
+ if (!IS_ERR(pdata->vdd))
+ regulator_disable(pdata->vdd);
+
+ if (!IS_ERR(pdata->vdd_io))
+ regulator_disable(pdata->vdd_io);
+}
+EXPORT_SYMBOL(st_sensors_power_disable);
+
static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
+#include <linux/delay.h>
#include <linux/hid-sensor-hub.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info gyro[GYRO_3D_CHANNEL_MAX];
u32 gyro_val[GYRO_3D_CHANNEL_MAX];
+ int scale_pre_decml;
+ int scale_post_decml;
+ int scale_precision;
+ int value_offset;
};
static const u32 gyro_3d_addresses[GYRO_3D_CHANNEL_MAX] = {
.type = IIO_ANGL_VEL,
.modified = 1,
.channel2 = IIO_MOD_X,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
.type = IIO_ANGL_VEL,
.modified = 1,
.channel2 = IIO_MOD_Y,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
.type = IIO_ANGL_VEL,
.modified = 1,
.channel2 = IIO_MOD_Z,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
u32 address;
int ret;
int ret_type;
+ s32 poll_value;
*val = 0;
*val2 = 0;
switch (mask) {
case 0:
+ poll_value = hid_sensor_read_poll_value(
+ &gyro_state->common_attributes);
+ if (poll_value < 0)
+ return -EINVAL;
+
+ hid_sensor_power_state(&gyro_state->common_attributes, true);
+ msleep_interruptible(poll_value * 2);
report_id = gyro_state->gyro[chan->scan_index].report_id;
address = gyro_3d_addresses[chan->scan_index];
if (report_id >= 0)
*val = sensor_hub_input_attr_get_raw_value(
- gyro_state->common_attributes.hsdev,
- HID_USAGE_SENSOR_GYRO_3D, address,
- report_id);
+ gyro_state->common_attributes.hsdev,
+ HID_USAGE_SENSOR_GYRO_3D, address,
+ report_id);
else {
*val = 0;
+ hid_sensor_power_state(&gyro_state->common_attributes,
+ false);
return -EINVAL;
}
+ hid_sensor_power_state(&gyro_state->common_attributes, false);
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
- *val = gyro_state->gyro[CHANNEL_SCAN_INDEX_X].units;
- ret_type = IIO_VAL_INT;
+ *val = gyro_state->scale_pre_decml;
+ *val2 = gyro_state->scale_post_decml;
+ ret_type = gyro_state->scale_precision;
break;
case IIO_CHAN_INFO_OFFSET:
- *val = hid_sensor_convert_exponent(
- gyro_state->gyro[CHANNEL_SCAN_INDEX_X].unit_expo);
+ *val = gyro_state->value_offset;
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
- dev_dbg(&indio_dev->dev, "gyro_3d_proc_event [%d]\n",
- gyro_state->common_attributes.data_ready);
- if (gyro_state->common_attributes.data_ready)
+ dev_dbg(&indio_dev->dev, "gyro_3d_proc_event\n");
+ if (atomic_read(&gyro_state->common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
gyro_state->gyro_val,
sizeof(gyro_state->gyro_val));
st->gyro[1].index, st->gyro[1].report_id,
st->gyro[2].index, st->gyro[2].report_id);
+ st->scale_precision = hid_sensor_format_scale(
+ HID_USAGE_SENSOR_GYRO_3D,
+ &st->gyro[CHANNEL_SCAN_INDEX_X],
+ &st->scale_pre_decml, &st->scale_post_decml);
+
/* Set Sensitivity field ids, when there is no individual modifier */
if (st->common_attributes.sensitivity.index < 0) {
sensor_hub_input_get_attribute_info(hsdev,
dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
goto error_free_dev_mem;
}
- gyro_state->common_attributes.data_ready = false;
+ atomic_set(&gyro_state->common_attributes.data_ready, 0);
ret = hid_sensor_setup_trigger(indio_dev, name,
&gyro_state->common_attributes);
if (ret < 0) {
default:
return -EINVAL;
}
-
- return ret;
}
static ssize_t itg3200_read_frequency(struct device *dev,
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &gyro_info;
+ st_sensors_power_enable(indio_dev);
+
err = st_sensors_check_device_support(indio_dev,
ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors);
if (err < 0)
if (err)
goto st_gyro_device_register_error;
+ dev_info(&indio_dev->dev, "registered gyroscope %s\n",
+ indio_dev->name);
+
return 0;
st_gyro_device_register_error:
{
struct st_sensor_data *gdata = iio_priv(indio_dev);
+ st_sensors_power_disable(indio_dev);
+
iio_device_unregister(indio_dev);
if (gdata->get_irq_data_ready(indio_dev) > 0)
st_sensors_deallocate_trigger(indio_dev);
struct list_head *attr_list);
void iio_free_chan_devattr_list(struct list_head *attr_list);
-ssize_t iio_format_value(char *buf, unsigned int type, int val, int val2);
+ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals);
/* Event interface flags */
#define IIO_BUSY_BIT_POS 1
select IIO_TRIGGERED_BUFFER
help
This driver supports the Invensense MPU6050 devices.
+ This driver can also support MPU6500 in MPU6050 compatibility mode
+ and also in MPU6500 mode with some limitations.
It is a gyroscope/accelerometer combo device.
This driver can be built as a module. The module will be called
inv-mpu6050.
*/
static const struct i2c_device_id inv_mpu_id[] = {
{"mpu6050", INV_MPU6050},
+ {"mpu6500", INV_MPU6500},
{}
};
/*device enum */
enum inv_devices {
INV_MPU6050,
+ INV_MPU6500,
INV_NUM_PARTS
};
type = IIO_BE;
#endif
}
- return sprintf(buf, "%s:%c%d/%d>>%u\n",
+ if (this_attr->c->scan_type.repeat > 1)
+ return sprintf(buf, "%s:%c%d/%dX%d>>%u\n",
+ iio_endian_prefix[type],
+ this_attr->c->scan_type.sign,
+ this_attr->c->scan_type.realbits,
+ this_attr->c->scan_type.storagebits,
+ this_attr->c->scan_type.repeat,
+ this_attr->c->scan_type.shift);
+ else
+ return sprintf(buf, "%s:%c%d/%d>>%u\n",
iio_endian_prefix[type],
this_attr->c->scan_type.sign,
this_attr->c->scan_type.realbits,
int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- ret = test_bit(to_iio_dev_attr(attr)->address,
+ /* Ensure ret is 0 or 1. */
+ ret = !!test_bit(to_iio_dev_attr(attr)->address,
indio_dev->buffer->scan_mask);
return sprintf(buf, "%d\n", ret);
for_each_set_bit(i, mask,
indio_dev->masklength) {
ch = iio_find_channel_from_si(indio_dev, i);
- length = ch->scan_type.storagebits / 8;
+ if (ch->scan_type.repeat > 1)
+ length = ch->scan_type.storagebits / 8 *
+ ch->scan_type.repeat;
+ else
+ length = ch->scan_type.storagebits / 8;
bytes = ALIGN(bytes, length);
bytes += length;
}
if (timestamp) {
ch = iio_find_channel_from_si(indio_dev,
indio_dev->scan_index_timestamp);
- length = ch->scan_type.storagebits / 8;
+ if (ch->scan_type.repeat > 1)
+ length = ch->scan_type.storagebits / 8 *
+ ch->scan_type.repeat;
+ else
+ length = ch->scan_type.storagebits / 8;
bytes = ALIGN(bytes, length);
bytes += length;
}
if (!buffer->scan_mask)
return 0;
- return test_bit(bit, buffer->scan_mask);
+ /* Ensure return value is 0 or 1. */
+ return !!test_bit(bit, buffer->scan_mask);
};
EXPORT_SYMBOL_GPL(iio_scan_mask_query);
indio_dev->masklength,
in_ind + 1);
ch = iio_find_channel_from_si(indio_dev, in_ind);
- length = ch->scan_type.storagebits/8;
+ if (ch->scan_type.repeat > 1)
+ length = ch->scan_type.storagebits / 8 *
+ ch->scan_type.repeat;
+ else
+ length = ch->scan_type.storagebits / 8;
/* Make sure we are aligned */
in_loc += length;
if (in_loc % length)
goto error_clear_mux_table;
}
ch = iio_find_channel_from_si(indio_dev, in_ind);
- length = ch->scan_type.storagebits/8;
+ if (ch->scan_type.repeat > 1)
+ length = ch->scan_type.storagebits / 8 *
+ ch->scan_type.repeat;
+ else
+ length = ch->scan_type.storagebits / 8;
if (out_loc % length)
out_loc += length - out_loc % length;
if (in_loc % length)
}
ch = iio_find_channel_from_si(indio_dev,
indio_dev->scan_index_timestamp);
- length = ch->scan_type.storagebits/8;
+ if (ch->scan_type.repeat > 1)
+ length = ch->scan_type.storagebits / 8 *
+ ch->scan_type.repeat;
+ else
+ length = ch->scan_type.storagebits / 8;
if (out_loc % length)
out_loc += length - out_loc % length;
if (in_loc % length)
[IIO_MOD_LIGHT_RED] = "red",
[IIO_MOD_LIGHT_GREEN] = "green",
[IIO_MOD_LIGHT_BLUE] = "blue",
+ [IIO_MOD_QUATERNION] = "quaternion",
+ [IIO_MOD_TEMP_AMBIENT] = "ambient",
+ [IIO_MOD_TEMP_OBJECT] = "object",
};
/* relies on pairs of these shared then separate */
else if (i >= e->num_items)
return -EINVAL;
- return sprintf(buf, "%s\n", e->items[i]);
+ return snprintf(buf, PAGE_SIZE, "%s\n", e->items[i]);
}
EXPORT_SYMBOL_GPL(iio_enum_read);
* @buf: The buffer to which the formated value gets written
* @type: One of the IIO_VAL_... constants. This decides how the val and val2
* parameters are formatted.
- * @val: First part of the value, exact meaning depends on the type parameter.
- * @val2: Second part of the value, exact meaning depends on the type parameter.
+ * @vals: pointer to the values, exact meaning depends on the type parameter.
*/
-ssize_t iio_format_value(char *buf, unsigned int type, int val, int val2)
+ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals)
{
unsigned long long tmp;
bool scale_db = false;
switch (type) {
case IIO_VAL_INT:
- return sprintf(buf, "%d\n", val);
+ return sprintf(buf, "%d\n", vals[0]);
case IIO_VAL_INT_PLUS_MICRO_DB:
scale_db = true;
case IIO_VAL_INT_PLUS_MICRO:
- if (val2 < 0)
- return sprintf(buf, "-%ld.%06u%s\n", abs(val), -val2,
+ if (vals[1] < 0)
+ return sprintf(buf, "-%ld.%06u%s\n", abs(vals[0]),
+ -vals[1],
scale_db ? " dB" : "");
else
- return sprintf(buf, "%d.%06u%s\n", val, val2,
+ return sprintf(buf, "%d.%06u%s\n", vals[0], vals[1],
scale_db ? " dB" : "");
case IIO_VAL_INT_PLUS_NANO:
- if (val2 < 0)
- return sprintf(buf, "-%ld.%09u\n", abs(val), -val2);
+ if (vals[1] < 0)
+ return sprintf(buf, "-%ld.%09u\n", abs(vals[0]),
+ -vals[1]);
else
- return sprintf(buf, "%d.%09u\n", val, val2);
+ return sprintf(buf, "%d.%09u\n", vals[0], vals[1]);
case IIO_VAL_FRACTIONAL:
- tmp = div_s64((s64)val * 1000000000LL, val2);
- val2 = do_div(tmp, 1000000000LL);
- val = tmp;
- return sprintf(buf, "%d.%09u\n", val, val2);
+ tmp = div_s64((s64)vals[0] * 1000000000LL, vals[1]);
+ vals[1] = do_div(tmp, 1000000000LL);
+ vals[0] = tmp;
+ return sprintf(buf, "%d.%09u\n", vals[0], vals[1]);
case IIO_VAL_FRACTIONAL_LOG2:
- tmp = (s64)val * 1000000000LL >> val2;
- val2 = do_div(tmp, 1000000000LL);
- val = tmp;
- return sprintf(buf, "%d.%09u\n", val, val2);
+ tmp = (s64)vals[0] * 1000000000LL >> vals[1];
+ vals[1] = do_div(tmp, 1000000000LL);
+ vals[0] = tmp;
+ return sprintf(buf, "%d.%09u\n", vals[0], vals[1]);
+ case IIO_VAL_INT_MULTIPLE:
+ {
+ int i;
+ int len = 0;
+
+ for (i = 0; i < size; ++i)
+ len += snprintf(&buf[len], PAGE_SIZE - len, "%d ",
+ vals[i]);
+ len += snprintf(&buf[len], PAGE_SIZE - len, "\n");
+ return len;
+ }
default:
return 0;
}
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- int val, val2;
- int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
- &val, &val2, this_attr->address);
+ int vals[INDIO_MAX_RAW_ELEMENTS];
+ int ret;
+ int val_len = 2;
+
+ if (indio_dev->info->read_raw_multi)
+ ret = indio_dev->info->read_raw_multi(indio_dev, this_attr->c,
+ INDIO_MAX_RAW_ELEMENTS,
+ vals, &val_len,
+ this_attr->address);
+ else
+ ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
+ &vals[0], &vals[1], this_attr->address);
if (ret < 0)
return ret;
- return iio_format_value(buf, ret, val, val2);
+ return iio_format_value(buf, ret, val_len, vals);
}
/**
int i, ret, attrcount = 0;
for_each_set_bit(i, infomask, sizeof(infomask)*8) {
+ if (i >= ARRAY_SIZE(iio_chan_info_postfix))
+ return -EINVAL;
ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
chan,
&iio_read_channel_info,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- return sprintf(buf, "%s\n", indio_dev->name);
+ return snprintf(buf, PAGE_SIZE, "%s\n", indio_dev->name);
}
static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL);
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- int val, val2;
+ int val, val2, val_arr[2];
int ret;
ret = indio_dev->info->read_event_value(indio_dev,
&val, &val2);
if (ret < 0)
return ret;
- return iio_format_value(buf, ret, val, val2);
+ val_arr[0] = val;
+ val_arr[1] = val2;
+ return iio_format_value(buf, ret, 2, val_arr);
}
static ssize_t iio_ev_value_store(struct device *dev,
char *postfix;
int ret;
- for_each_set_bit(i, mask, sizeof(*mask)) {
+ for_each_set_bit(i, mask, sizeof(*mask)*8) {
+ if (i >= ARRAY_SIZE(iio_ev_info_text))
+ return -EINVAL;
postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
iio_ev_type_text[type], iio_ev_dir_text[dir],
iio_ev_info_text[i]);
enum iio_chan_info_enum info)
{
int unused;
+ int vals[INDIO_MAX_RAW_ELEMENTS];
+ int ret;
+ int val_len = 2;
if (val2 == NULL)
val2 = &unused;
- return chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel,
- val, val2, info);
+ if (chan->indio_dev->info->read_raw_multi) {
+ ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev,
+ chan->channel, INDIO_MAX_RAW_ELEMENTS,
+ vals, &val_len, info);
+ *val = vals[0];
+ *val2 = vals[1];
+ } else
+ ret = chan->indio_dev->info->read_raw(chan->indio_dev,
+ chan->channel, val, val2, info);
+
+ return ret;
}
int iio_read_channel_raw(struct iio_channel *chan, int *val)
}
EXPORT_SYMBOL_GPL(iio_read_channel_raw);
+int iio_read_channel_average_raw(struct iio_channel *chan, int *val)
+{
+ int ret;
+
+ mutex_lock(&chan->indio_dev->info_exist_lock);
+ if (chan->indio_dev->info == NULL) {
+ ret = -ENODEV;
+ goto err_unlock;
+ }
+
+ ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_AVERAGE_RAW);
+err_unlock:
+ mutex_unlock(&chan->indio_dev->info_exist_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(iio_read_channel_average_raw);
+
static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
int raw, int *processed, unsigned int scale)
{
*val = cm32181->calibscale;
return IIO_VAL_INT;
case IIO_CHAN_INFO_INT_TIME:
+ *val = 0;
ret = cm32181_read_als_it(cm32181, val2);
return ret;
}
cm36651->client = client;
cm36651->ps_client = i2c_new_dummy(client->adapter,
CM36651_I2C_ADDR_PS);
+ if (!cm36651->ps_client) {
+ dev_err(&client->dev, "%s: new i2c device failed\n", __func__);
+ ret = -ENODEV;
+ goto error_disable_reg;
+ }
+
cm36651->ara_client = i2c_new_dummy(client->adapter, CM36651_ARA);
+ if (!cm36651->ara_client) {
+ dev_err(&client->dev, "%s: new i2c device failed\n", __func__);
+ ret = -ENODEV;
+ goto error_i2c_unregister_ps;
+ }
+
mutex_init(&cm36651->lock);
indio_dev->dev.parent = &client->dev;
indio_dev->channels = cm36651_channels;
ret = cm36651_setup_reg(cm36651);
if (ret) {
dev_err(&client->dev, "%s: register setup failed\n", __func__);
- goto error_disable_reg;
+ goto error_i2c_unregister_ara;
}
ret = request_threaded_irq(client->irq, NULL, cm36651_irq_handler,
"cm36651", indio_dev);
if (ret) {
dev_err(&client->dev, "%s: request irq failed\n", __func__);
- goto error_disable_reg;
+ goto error_i2c_unregister_ara;
}
ret = iio_device_register(indio_dev);
error_free_irq:
free_irq(client->irq, indio_dev);
+error_i2c_unregister_ara:
+ i2c_unregister_device(cm36651->ara_client);
+error_i2c_unregister_ps:
+ i2c_unregister_device(cm36651->ps_client);
error_disable_reg:
regulator_disable(cm36651->vled_reg);
return ret;
iio_device_unregister(indio_dev);
regulator_disable(cm36651->vled_reg);
free_irq(client->irq, indio_dev);
+ i2c_unregister_device(cm36651->ps_client);
+ i2c_unregister_device(cm36651->ara_client);
return 0;
}
* IIO features supported by the driver:
*
* Read-only raw channels:
- * - illiminance_clear [lux]
- * - illiminance_ir
+ * - illuminance_clear [lux]
+ * - illuminance_ir
* - proximity
*
* Triggered buffer:
- * - illiminance_clear
- * - illiminance_ir
+ * - illuminance_clear
+ * - illuminance_ir
* - proximity
*
* Events:
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
+#include <linux/delay.h>
#include <linux/hid-sensor-hub.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info als_illum;
u32 illum;
+ int scale_pre_decml;
+ int scale_post_decml;
+ int scale_precision;
+ int value_offset;
};
/* Channel definitions */
.type = IIO_INTENSITY,
.modified = 1,
.channel2 = IIO_MOD_LIGHT_BOTH,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
u32 address;
int ret;
int ret_type;
+ s32 poll_value;
*val = 0;
*val2 = 0;
report_id = -1;
break;
}
- if (report_id >= 0)
+ if (report_id >= 0) {
+ poll_value = hid_sensor_read_poll_value(
+ &als_state->common_attributes);
+ if (poll_value < 0)
+ return -EINVAL;
+
+ hid_sensor_power_state(&als_state->common_attributes,
+ true);
+ msleep_interruptible(poll_value * 2);
+
*val = sensor_hub_input_attr_get_raw_value(
- als_state->common_attributes.hsdev,
- HID_USAGE_SENSOR_ALS, address,
- report_id);
- else {
+ als_state->common_attributes.hsdev,
+ HID_USAGE_SENSOR_ALS, address,
+ report_id);
+ hid_sensor_power_state(&als_state->common_attributes,
+ false);
+ } else {
*val = 0;
return -EINVAL;
}
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
- *val = als_state->als_illum.units;
- ret_type = IIO_VAL_INT;
+ *val = als_state->scale_pre_decml;
+ *val2 = als_state->scale_post_decml;
+ ret_type = als_state->scale_precision;
break;
case IIO_CHAN_INFO_OFFSET:
- *val = hid_sensor_convert_exponent(
- als_state->als_illum.unit_expo);
+ *val = als_state->value_offset;
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct als_state *als_state = iio_priv(indio_dev);
- dev_dbg(&indio_dev->dev, "als_proc_event [%d]\n",
- als_state->common_attributes.data_ready);
- if (als_state->common_attributes.data_ready)
+ dev_dbg(&indio_dev->dev, "als_proc_event\n");
+ if (atomic_read(&als_state->common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
&als_state->illum,
sizeof(als_state->illum));
dev_dbg(&pdev->dev, "als %x:%x\n", st->als_illum.index,
st->als_illum.report_id);
+ st->scale_precision = hid_sensor_format_scale(
+ HID_USAGE_SENSOR_ALS,
+ &st->als_illum,
+ &st->scale_pre_decml, &st->scale_post_decml);
+
/* Set Sensitivity field ids, when there is no individual modifier */
if (st->common_attributes.sensitivity.index < 0) {
sensor_hub_input_get_attribute_info(hsdev,
dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
goto error_free_dev_mem;
}
- als_state->common_attributes.data_ready = false;
+ atomic_set(&als_state->common_attributes.data_ready, 0);
ret = hid_sensor_setup_trigger(indio_dev, name,
&als_state->common_attributes);
if (ret < 0) {
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
+#include <linux/delay.h>
#include <linux/hid-sensor-hub.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
u32 address;
int ret;
int ret_type;
+ s32 poll_value;
*val = 0;
*val2 = 0;
report_id = -1;
break;
}
- if (report_id >= 0)
+ if (report_id >= 0) {
+ poll_value = hid_sensor_read_poll_value(
+ &prox_state->common_attributes);
+ if (poll_value < 0)
+ return -EINVAL;
+
+ hid_sensor_power_state(&prox_state->common_attributes,
+ true);
+
+ msleep_interruptible(poll_value * 2);
+
*val = sensor_hub_input_attr_get_raw_value(
prox_state->common_attributes.hsdev,
HID_USAGE_SENSOR_PROX, address,
report_id);
- else {
+ hid_sensor_power_state(&prox_state->common_attributes,
+ false);
+ } else {
*val = 0;
return -EINVAL;
}
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct prox_state *prox_state = iio_priv(indio_dev);
- dev_dbg(&indio_dev->dev, "prox_proc_event [%d]\n",
- prox_state->common_attributes.data_ready);
- if (prox_state->common_attributes.data_ready)
+ dev_dbg(&indio_dev->dev, "prox_proc_event\n");
+ if (atomic_read(&prox_state->common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
&prox_state->human_presence,
sizeof(prox_state->human_presence));
dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
goto error_free_dev_mem;
}
- prox_state->common_attributes.data_ready = false;
+ atomic_set(&prox_state->common_attributes.data_ready, 0);
ret = hid_sensor_setup_trigger(indio_dev, name,
&prox_state->common_attributes);
if (ret) {
depends on GPIOLIB
help
Say yes here to build support for Asahi Kasei AK8975 3-Axis
- Magnetometer.
+ Magnetometer. This driver can also support AK8963, if i2c
+ device name is identified as ak8963.
To compile this driver as a module, choose M here: the module
will be called ak8975.
#include <linux/bitops.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
+#include <linux/acpi.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#define AK8975_MAX_CONVERSION_TIMEOUT 500
#define AK8975_CONVERSION_DONE_POLL_TIME 10
#define AK8975_DATA_READY_TIMEOUT ((100*HZ)/1000)
-#define RAW_TO_GAUSS(asa) ((((asa) + 128) * 3000) / 256)
+#define RAW_TO_GAUSS_8975(asa) ((((asa) + 128) * 3000) / 256)
+#define RAW_TO_GAUSS_8963(asa) ((((asa) + 128) * 6000) / 256)
+
+/* Compatible Asahi Kasei Compass parts */
+enum asahi_compass_chipset {
+ AK8975,
+ AK8963,
+};
/*
* Per-instance context data for the device.
int eoc_irq;
wait_queue_head_t data_ready_queue;
unsigned long flags;
+ enum asahi_compass_chipset chipset;
};
static const int ak8975_index_to_reg[] = {
* Since ASA doesn't change, we cache the resultant scale factor into the
* device context in ak8975_setup().
*/
- data->raw_to_gauss[0] = RAW_TO_GAUSS(data->asa[0]);
- data->raw_to_gauss[1] = RAW_TO_GAUSS(data->asa[1]);
- data->raw_to_gauss[2] = RAW_TO_GAUSS(data->asa[2]);
+ if (data->chipset == AK8963) {
+ /*
+ * H range is +-8190 and magnetometer range is +-4912.
+ * So HuT using the above explanation for 8975,
+ * 4912/8190 = ~ 6/10.
+ * So the Hadj should use 6/10 instead of 3/10.
+ */
+ data->raw_to_gauss[0] = RAW_TO_GAUSS_8963(data->asa[0]);
+ data->raw_to_gauss[1] = RAW_TO_GAUSS_8963(data->asa[1]);
+ data->raw_to_gauss[2] = RAW_TO_GAUSS_8963(data->asa[2]);
+ } else {
+ data->raw_to_gauss[0] = RAW_TO_GAUSS_8975(data->asa[0]);
+ data->raw_to_gauss[1] = RAW_TO_GAUSS_8975(data->asa[1]);
+ data->raw_to_gauss[2] = RAW_TO_GAUSS_8975(data->asa[2]);
+ }
return 0;
}
.driver_module = THIS_MODULE,
};
+static const struct acpi_device_id ak_acpi_match[] = {
+ {"AK8975", AK8975},
+ {"AK8963", AK8963},
+ {"INVN6500", AK8963},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, ak_acpi_match);
+
+static char *ak8975_match_acpi_device(struct device *dev,
+ enum asahi_compass_chipset *chipset)
+{
+ const struct acpi_device_id *id;
+
+ id = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!id)
+ return NULL;
+ *chipset = (int)id->driver_data;
+
+ return (char *)dev_name(dev);
+}
+
static int ak8975_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *indio_dev;
int eoc_gpio;
int err;
+ char *name = NULL;
/* Grab and set up the supplied GPIO. */
if (client->dev.platform_data)
data->eoc_gpio = eoc_gpio;
data->eoc_irq = 0;
+ /* id will be NULL when enumerated via ACPI */
+ if (id) {
+ data->chipset =
+ (enum asahi_compass_chipset)(id->driver_data);
+ name = (char *) id->name;
+ } else if (ACPI_HANDLE(&client->dev))
+ name = ak8975_match_acpi_device(&client->dev, &data->chipset);
+ else {
+ err = -ENOSYS;
+ goto exit_free_iio;
+ }
+ dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
+
/* Perform some basic start-of-day setup of the device. */
err = ak8975_setup(client);
if (err < 0) {
indio_dev->channels = ak8975_channels;
indio_dev->num_channels = ARRAY_SIZE(ak8975_channels);
indio_dev->info = &ak8975_info;
- indio_dev->name = id->name;
indio_dev->modes = INDIO_DIRECT_MODE;
-
+ indio_dev->name = name;
err = iio_device_register(indio_dev);
if (err < 0)
goto exit_free_iio;
}
static const struct i2c_device_id ak8975_id[] = {
- {"ak8975", 0},
+ {"ak8975", AK8975},
+ {"ak8963", AK8963},
{}
};
.driver = {
.name = "ak8975",
.of_match_table = ak8975_of_match,
+ .acpi_match_table = ACPI_PTR(ak_acpi_match),
},
.probe = ak8975_probe,
.remove = ak8975_remove,
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
+#include <linux/delay.h>
#include <linux/hid-sensor-hub.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
u32 magn_val[MAGN_3D_CHANNEL_MAX];
+ int scale_pre_decml;
+ int scale_post_decml;
+ int scale_precision;
+ int value_offset;
};
static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
.type = IIO_MAGN,
.modified = 1,
.channel2 = IIO_MOD_X,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
.type = IIO_MAGN,
.modified = 1,
.channel2 = IIO_MOD_Y,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
.type = IIO_MAGN,
.modified = 1,
.channel2 = IIO_MOD_Z,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
u32 address;
int ret;
int ret_type;
+ s32 poll_value;
*val = 0;
*val2 = 0;
switch (mask) {
case 0:
+ poll_value = hid_sensor_read_poll_value(
+ &magn_state->common_attributes);
+ if (poll_value < 0)
+ return -EINVAL;
+
+ hid_sensor_power_state(&magn_state->common_attributes, true);
+ msleep_interruptible(poll_value * 2);
+
report_id =
magn_state->magn[chan->scan_index].report_id;
address = magn_3d_addresses[chan->scan_index];
report_id);
else {
*val = 0;
+ hid_sensor_power_state(&magn_state->common_attributes,
+ false);
return -EINVAL;
}
+ hid_sensor_power_state(&magn_state->common_attributes, false);
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
- *val = magn_state->magn[CHANNEL_SCAN_INDEX_X].units;
- ret_type = IIO_VAL_INT;
+ *val = magn_state->scale_pre_decml;
+ *val2 = magn_state->scale_post_decml;
+ ret_type = magn_state->scale_precision;
break;
case IIO_CHAN_INFO_OFFSET:
- *val = hid_sensor_convert_exponent(
- magn_state->magn[CHANNEL_SCAN_INDEX_X].unit_expo);
+ *val = magn_state->value_offset;
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct magn_3d_state *magn_state = iio_priv(indio_dev);
- dev_dbg(&indio_dev->dev, "magn_3d_proc_event [%d]\n",
- magn_state->common_attributes.data_ready);
- if (magn_state->common_attributes.data_ready)
+ dev_dbg(&indio_dev->dev, "magn_3d_proc_event\n");
+ if (atomic_read(&magn_state->common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
magn_state->magn_val,
sizeof(magn_state->magn_val));
st->magn[1].index, st->magn[1].report_id,
st->magn[2].index, st->magn[2].report_id);
+ st->scale_precision = hid_sensor_format_scale(
+ HID_USAGE_SENSOR_COMPASS_3D,
+ &st->magn[CHANNEL_SCAN_INDEX_X],
+ &st->scale_pre_decml, &st->scale_post_decml);
+
/* Set Sensitivity field ids, when there is no individual modifier */
if (st->common_attributes.sensitivity.index < 0) {
sensor_hub_input_get_attribute_info(hsdev,
dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
goto error_free_dev_mem;
}
- magn_state->common_attributes.data_ready = false;
+ atomic_set(&magn_state->common_attributes.data_ready, 0);
ret = hid_sensor_setup_trigger(indio_dev, name,
&magn_state->common_attributes);
if (ret < 0) {
*val = mag3110_samp_freq[i][0];
*val2 = mag3110_samp_freq[i][1];
return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_CALIBBIAS:
+ ret = i2c_smbus_read_word_swapped(data->client,
+ MAG3110_OFF_X + 2 * chan->scan_index);
+ if (ret < 0)
+ return ret;
+ *val = sign_extend32(ret >> 1, 14);
+ return IIO_VAL_INT;
}
return -EINVAL;
}
data->ctrl_reg1 |= rate << MAG3110_CTRL_DR_SHIFT;
return i2c_smbus_write_byte_data(data->client,
MAG3110_CTRL_REG1, data->ctrl_reg1);
+ case IIO_CHAN_INFO_CALIBBIAS:
+ if (val < -10000 || val > 10000)
+ return -EINVAL;
+ return i2c_smbus_write_word_swapped(data->client,
+ MAG3110_OFF_X + 2 * chan->scan_index, val << 1);
default:
return -EINVAL;
}
.type = IIO_MAGN, \
.modified = 1, \
.channel2 = IIO_MOD_##axis, \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_CALIBBIAS), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
BIT(IIO_CHAN_INFO_SCALE), \
.scan_index = idx, \
indio_dev->num_channels = ARRAY_SIZE(mag3110_channels);
indio_dev->available_scan_masks = mag3110_scan_masks;
- data->ctrl_reg1 = MAG3110_CTRL_DR_DEFAULT;
+ data->ctrl_reg1 = MAG3110_CTRL_DR_DEFAULT << MAG3110_CTRL_DR_SHIFT;
ret = i2c_smbus_write_byte_data(client, MAG3110_CTRL_REG1,
data->ctrl_reg1);
if (ret < 0)
return ret;
ret = i2c_smbus_write_byte_data(client, MAG3110_CTRL_REG2,
- MAG3110_CTRL_AUTO_MRST_EN | MAG3110_CTRL_RAW);
+ MAG3110_CTRL_AUTO_MRST_EN);
if (ret < 0)
return ret;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &magn_info;
+ st_sensors_power_enable(indio_dev);
+
err = st_sensors_check_device_support(indio_dev,
ARRAY_SIZE(st_magn_sensors), st_magn_sensors);
if (err < 0)
if (err)
goto st_magn_device_register_error;
+ dev_info(&indio_dev->dev, "registered magnetometer %s\n",
+ indio_dev->name);
+
return 0;
st_magn_device_register_error:
{
struct st_sensor_data *mdata = iio_priv(indio_dev);
+ st_sensors_power_disable(indio_dev);
+
iio_device_unregister(indio_dev);
if (mdata->get_irq_data_ready(indio_dev) > 0)
st_sensors_deallocate_trigger(indio_dev);
Say yes here to build support for the HID SENSOR
Inclinometer 3D.
+config HID_SENSOR_DEVICE_ROTATION
+ depends on HID_SENSOR_HUB
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ select HID_SENSOR_IIO_COMMON
+ select HID_SENSOR_IIO_TRIGGER
+ tristate "HID Device Rotation"
+ help
+ Say yes here to build support for the HID SENSOR
+ device rotation. The output of a device rotation sensor
+ is presented using quaternion format.
+
endmenu
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_HID_SENSOR_INCLINOMETER_3D) += hid-sensor-incl-3d.o
+obj-$(CONFIG_HID_SENSOR_DEVICE_ROTATION) += hid-sensor-rotation.o
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
+#include <linux/delay.h>
#include <linux/hid-sensor-hub.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info incl[INCLI_3D_CHANNEL_MAX];
u32 incl_val[INCLI_3D_CHANNEL_MAX];
+ int scale_pre_decml;
+ int scale_post_decml;
+ int scale_precision;
+ int value_offset;
};
static const u32 incl_3d_addresses[INCLI_3D_CHANNEL_MAX] = {
int report_id = -1;
u32 address;
int ret_type;
+ s32 poll_value;
*val = 0;
*val2 = 0;
switch (mask) {
case IIO_CHAN_INFO_RAW:
+ poll_value = hid_sensor_read_poll_value(
+ &incl_state->common_attributes);
+ if (poll_value < 0)
+ return -EINVAL;
+
+ hid_sensor_power_state(&incl_state->common_attributes, true);
+ msleep_interruptible(poll_value * 2);
+
report_id =
incl_state->incl[chan->scan_index].report_id;
address = incl_3d_addresses[chan->scan_index];
HID_USAGE_SENSOR_INCLINOMETER_3D, address,
report_id);
else {
+ hid_sensor_power_state(&incl_state->common_attributes,
+ false);
return -EINVAL;
}
+ hid_sensor_power_state(&incl_state->common_attributes, false);
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
- *val = incl_state->incl[CHANNEL_SCAN_INDEX_X].units;
- ret_type = IIO_VAL_INT;
+ *val = incl_state->scale_pre_decml;
+ *val2 = incl_state->scale_post_decml;
+ ret_type = incl_state->scale_precision;
break;
case IIO_CHAN_INFO_OFFSET:
- *val = hid_sensor_convert_exponent(
- incl_state->incl[CHANNEL_SCAN_INDEX_X].unit_expo);
+ *val = incl_state->value_offset;
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct incl_3d_state *incl_state = iio_priv(indio_dev);
- dev_dbg(&indio_dev->dev, "incl_3d_proc_event [%d]\n",
- incl_state->common_attributes.data_ready);
- if (incl_state->common_attributes.data_ready)
+ dev_dbg(&indio_dev->dev, "incl_3d_proc_event\n");
+ if (atomic_read(&incl_state->common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
(u8 *)incl_state->incl_val,
sizeof(incl_state->incl_val));
st->incl[1].index, st->incl[1].report_id,
st->incl[2].index, st->incl[2].report_id);
+ st->scale_precision = hid_sensor_format_scale(
+ HID_USAGE_SENSOR_INCLINOMETER_3D,
+ &st->incl[CHANNEL_SCAN_INDEX_X],
+ &st->scale_pre_decml, &st->scale_post_decml);
+
/* Set Sensitivity field ids, when there is no individual modifier */
if (st->common_attributes.sensitivity.index < 0) {
sensor_hub_input_get_attribute_info(hsdev,
dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
goto error_free_dev_mem;
}
- incl_state->common_attributes.data_ready = false;
+ atomic_set(&incl_state->common_attributes.data_ready, 0);
ret = hid_sensor_setup_trigger(indio_dev, name,
&incl_state->common_attributes);
if (ret) {
--- /dev/null
+/*
+ * HID Sensors Driver
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * 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 <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/hid-sensor-hub.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include "../common/hid-sensors/hid-sensor-trigger.h"
+
+struct dev_rot_state {
+ struct hid_sensor_hub_callbacks callbacks;
+ struct hid_sensor_common common_attributes;
+ struct hid_sensor_hub_attribute_info quaternion;
+ u32 sampled_vals[4];
+};
+
+/* Channel definitions */
+static const struct iio_chan_spec dev_rot_channels[] = {
+ {
+ .type = IIO_ROT,
+ .modified = 1,
+ .channel2 = IIO_MOD_QUATERNION,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS)
+ }
+};
+
+/* Adjust channel real bits based on report descriptor */
+static void dev_rot_adjust_channel_bit_mask(struct iio_chan_spec *chan,
+ int size)
+{
+ chan->scan_type.sign = 's';
+ /* Real storage bits will change based on the report desc. */
+ chan->scan_type.realbits = size * 8;
+ /* Maximum size of a sample to capture is u32 */
+ chan->scan_type.storagebits = sizeof(u32) * 8;
+ chan->scan_type.repeat = 4;
+}
+
+/* Channel read_raw handler */
+static int dev_rot_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int size, int *vals, int *val_len,
+ long mask)
+{
+ struct dev_rot_state *rot_state = iio_priv(indio_dev);
+ int ret_type;
+ int i;
+
+ vals[0] = 0;
+ vals[1] = 0;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (size >= 4) {
+ for (i = 0; i < 4; ++i)
+ vals[i] = rot_state->sampled_vals[i];
+ ret_type = IIO_VAL_INT_MULTIPLE;
+ *val_len = 4;
+ } else
+ ret_type = -EINVAL;
+ break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ ret_type = hid_sensor_read_samp_freq_value(
+ &rot_state->common_attributes, &vals[0], &vals[1]);
+ break;
+ case IIO_CHAN_INFO_HYSTERESIS:
+ ret_type = hid_sensor_read_raw_hyst_value(
+ &rot_state->common_attributes, &vals[0], &vals[1]);
+ break;
+ default:
+ ret_type = -EINVAL;
+ break;
+ }
+
+ return ret_type;
+}
+
+/* Channel write_raw handler */
+static int dev_rot_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val,
+ int val2,
+ long mask)
+{
+ struct dev_rot_state *rot_state = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ ret = hid_sensor_write_samp_freq_value(
+ &rot_state->common_attributes, val, val2);
+ break;
+ case IIO_CHAN_INFO_HYSTERESIS:
+ ret = hid_sensor_write_raw_hyst_value(
+ &rot_state->common_attributes, val, val2);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct iio_info dev_rot_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw_multi = &dev_rot_read_raw,
+ .write_raw = &dev_rot_write_raw,
+};
+
+/* Function to push data to buffer */
+static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
+{
+ dev_dbg(&indio_dev->dev, "hid_sensor_push_data >>\n");
+ iio_push_to_buffers(indio_dev, (u8 *)data);
+ dev_dbg(&indio_dev->dev, "hid_sensor_push_data <<\n");
+
+}
+
+/* Callback handler to send event after all samples are received and captured */
+static int dev_rot_proc_event(struct hid_sensor_hub_device *hsdev,
+ unsigned usage_id,
+ void *priv)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(priv);
+ struct dev_rot_state *rot_state = iio_priv(indio_dev);
+
+ dev_dbg(&indio_dev->dev, "dev_rot_proc_event\n");
+ if (atomic_read(&rot_state->common_attributes.data_ready))
+ hid_sensor_push_data(indio_dev,
+ (u8 *)rot_state->sampled_vals,
+ sizeof(rot_state->sampled_vals));
+
+ return 0;
+}
+
+/* Capture samples in local storage */
+static int dev_rot_capture_sample(struct hid_sensor_hub_device *hsdev,
+ unsigned usage_id,
+ size_t raw_len, char *raw_data,
+ void *priv)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(priv);
+ struct dev_rot_state *rot_state = iio_priv(indio_dev);
+
+ if (usage_id == HID_USAGE_SENSOR_ORIENT_QUATERNION) {
+ memcpy(rot_state->sampled_vals, raw_data,
+ sizeof(rot_state->sampled_vals));
+ dev_dbg(&indio_dev->dev, "Recd Quat len:%zu::%zu\n", raw_len,
+ sizeof(rot_state->sampled_vals));
+ }
+
+ return 0;
+}
+
+/* Parse report which is specific to an usage id*/
+static int dev_rot_parse_report(struct platform_device *pdev,
+ struct hid_sensor_hub_device *hsdev,
+ struct iio_chan_spec *channels,
+ unsigned usage_id,
+ struct dev_rot_state *st)
+{
+ int ret;
+
+ ret = sensor_hub_input_get_attribute_info(hsdev,
+ HID_INPUT_REPORT,
+ usage_id,
+ HID_USAGE_SENSOR_ORIENT_QUATERNION,
+ &st->quaternion);
+ if (ret)
+ return ret;
+
+ dev_rot_adjust_channel_bit_mask(&channels[0],
+ st->quaternion.size / 4);
+
+ dev_dbg(&pdev->dev, "dev_rot %x:%x\n", st->quaternion.index,
+ st->quaternion.report_id);
+
+ dev_dbg(&pdev->dev, "dev_rot: attrib size %d\n",
+ st->quaternion.size);
+
+ /* Set Sensitivity field ids, when there is no individual modifier */
+ if (st->common_attributes.sensitivity.index < 0) {
+ sensor_hub_input_get_attribute_info(hsdev,
+ HID_FEATURE_REPORT, usage_id,
+ HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS |
+ HID_USAGE_SENSOR_DATA_ORIENTATION,
+ &st->common_attributes.sensitivity);
+ dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n",
+ st->common_attributes.sensitivity.index,
+ st->common_attributes.sensitivity.report_id);
+ }
+
+ return 0;
+}
+
+/* Function to initialize the processing for usage id */
+static int hid_dev_rot_probe(struct platform_device *pdev)
+{
+ int ret;
+ static char *name = "dev_rotation";
+ struct iio_dev *indio_dev;
+ struct dev_rot_state *rot_state;
+ struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
+ struct iio_chan_spec *channels;
+
+ indio_dev = devm_iio_device_alloc(&pdev->dev,
+ sizeof(struct dev_rot_state));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, indio_dev);
+
+ rot_state = iio_priv(indio_dev);
+ rot_state->common_attributes.hsdev = hsdev;
+ rot_state->common_attributes.pdev = pdev;
+
+ ret = hid_sensor_parse_common_attributes(hsdev,
+ HID_USAGE_SENSOR_DEVICE_ORIENTATION,
+ &rot_state->common_attributes);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to setup common attributes\n");
+ return ret;
+ }
+
+ channels = devm_kmemdup(&pdev->dev, dev_rot_channels,
+ sizeof(dev_rot_channels), GFP_KERNEL);
+ if (!channels) {
+ dev_err(&pdev->dev, "failed to duplicate channels\n");
+ return -ENOMEM;
+ }
+
+ ret = dev_rot_parse_report(pdev, hsdev, channels,
+ HID_USAGE_SENSOR_DEVICE_ORIENTATION, rot_state);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to setup attributes\n");
+ return ret;
+ }
+
+ indio_dev->channels = channels;
+ indio_dev->num_channels = ARRAY_SIZE(dev_rot_channels);
+ indio_dev->dev.parent = &pdev->dev;
+ indio_dev->info = &dev_rot_info;
+ indio_dev->name = name;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+ NULL, NULL);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
+ return ret;
+ }
+ atomic_set(&rot_state->common_attributes.data_ready, 0);
+ ret = hid_sensor_setup_trigger(indio_dev, name,
+ &rot_state->common_attributes);
+ if (ret) {
+ dev_err(&pdev->dev, "trigger setup failed\n");
+ goto error_unreg_buffer_funcs;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(&pdev->dev, "device register failed\n");
+ goto error_remove_trigger;
+ }
+
+ rot_state->callbacks.send_event = dev_rot_proc_event;
+ rot_state->callbacks.capture_sample = dev_rot_capture_sample;
+ rot_state->callbacks.pdev = pdev;
+ ret = sensor_hub_register_callback(hsdev,
+ HID_USAGE_SENSOR_DEVICE_ORIENTATION,
+ &rot_state->callbacks);
+ if (ret) {
+ dev_err(&pdev->dev, "callback reg failed\n");
+ goto error_iio_unreg;
+ }
+
+ return 0;
+
+error_iio_unreg:
+ iio_device_unregister(indio_dev);
+error_remove_trigger:
+ hid_sensor_remove_trigger(&rot_state->common_attributes);
+error_unreg_buffer_funcs:
+ iio_triggered_buffer_cleanup(indio_dev);
+ return ret;
+}
+
+/* Function to deinitialize the processing for usage id */
+static int hid_dev_rot_remove(struct platform_device *pdev)
+{
+ struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct dev_rot_state *rot_state = iio_priv(indio_dev);
+
+ sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_DEVICE_ORIENTATION);
+ iio_device_unregister(indio_dev);
+ hid_sensor_remove_trigger(&rot_state->common_attributes);
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ return 0;
+}
+
+static struct platform_device_id hid_dev_rot_ids[] = {
+ {
+ /* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+ .name = "HID-SENSOR-20008a",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_dev_rot_ids);
+
+static struct platform_driver hid_dev_rot_platform_driver = {
+ .id_table = hid_dev_rot_ids,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = hid_dev_rot_probe,
+ .remove = hid_dev_rot_remove,
+};
+module_platform_driver(hid_dev_rot_platform_driver);
+
+MODULE_DESCRIPTION("HID Sensor Device Rotation");
+MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
+MODULE_LICENSE("GPL");
To compile this driver as a module, choose M here: the module
will be called hid-sensor-press.
+config MPL115
+ tristate "Freescale MPL115A2 pressure sensor driver"
+ depends on I2C
+ help
+ Say yes here to build support for the Freescale MPL115A2
+ pressure sensor connected via I2C.
+
+ To compile this driver as a module, choose M here: the module
+ will be called mpl115.
+
config MPL3115
tristate "Freescale MPL3115A2 pressure sensor driver"
depends on I2C
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o
+obj-$(CONFIG_MPL115) += mpl115.o
obj-$(CONFIG_MPL3115) += mpl3115.o
obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o
st_pressure-y := st_pressure_core.o
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
+#include <linux/delay.h>
#include <linux/hid-sensor-hub.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info press_attr;
u32 press_data;
+ int scale_pre_decml;
+ int scale_post_decml;
+ int scale_precision;
+ int value_offset;
};
/* Channel definitions */
u32 address;
int ret;
int ret_type;
+ s32 poll_value;
*val = 0;
*val2 = 0;
report_id = -1;
break;
}
- if (report_id >= 0)
+ if (report_id >= 0) {
+ poll_value = hid_sensor_read_poll_value(
+ &press_state->common_attributes);
+ if (poll_value < 0)
+ return -EINVAL;
+ hid_sensor_power_state(&press_state->common_attributes,
+ true);
+
+ msleep_interruptible(poll_value * 2);
+
*val = sensor_hub_input_attr_get_raw_value(
press_state->common_attributes.hsdev,
HID_USAGE_SENSOR_PRESSURE, address,
report_id);
- else {
+ hid_sensor_power_state(&press_state->common_attributes,
+ false);
+ } else {
*val = 0;
return -EINVAL;
}
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
- *val = press_state->press_attr.units;
- ret_type = IIO_VAL_INT;
+ *val = press_state->scale_pre_decml;
+ *val2 = press_state->scale_post_decml;
+ ret_type = press_state->scale_precision;
break;
case IIO_CHAN_INFO_OFFSET:
- *val = hid_sensor_convert_exponent(
- press_state->press_attr.unit_expo);
+ *val = press_state->value_offset;
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct press_state *press_state = iio_priv(indio_dev);
- dev_dbg(&indio_dev->dev, "press_proc_event [%d]\n",
- press_state->common_attributes.data_ready);
- if (press_state->common_attributes.data_ready)
+ dev_dbg(&indio_dev->dev, "press_proc_event\n");
+ if (atomic_read(&press_state->common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
&press_state->press_data,
sizeof(press_state->press_data));
dev_dbg(&pdev->dev, "press %x:%x\n", st->press_attr.index,
st->press_attr.report_id);
+ st->scale_precision = hid_sensor_format_scale(
+ HID_USAGE_SENSOR_PRESSURE,
+ &st->press_attr,
+ &st->scale_pre_decml, &st->scale_post_decml);
+
/* Set Sensitivity field ids, when there is no individual modifier */
if (st->common_attributes.sensitivity.index < 0) {
sensor_hub_input_get_attribute_info(hsdev,
dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
goto error_free_dev_mem;
}
- press_state->common_attributes.data_ready = false;
+ atomic_set(&press_state->common_attributes.data_ready, 0);
ret = hid_sensor_setup_trigger(indio_dev, name,
&press_state->common_attributes);
if (ret) {
--- /dev/null
+/*
+ * mpl115.c - Support for Freescale MPL115A2 pressure/temperature sensor
+ *
+ * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * 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.
+ *
+ * (7-bit I2C slave address 0x60)
+ *
+ * TODO: shutdown pin
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/delay.h>
+
+#define MPL115_PADC 0x00 /* pressure ADC output value, MSB first, 10 bit */
+#define MPL115_TADC 0x02 /* temperature ADC output value, MSB first, 10 bit */
+#define MPL115_A0 0x04 /* 12 bit integer, 3 bit fraction */
+#define MPL115_B1 0x06 /* 2 bit integer, 13 bit fraction */
+#define MPL115_B2 0x08 /* 1 bit integer, 14 bit fraction */
+#define MPL115_C12 0x0a /* 0 bit integer, 13 bit fraction */
+#define MPL115_CONVERT 0x12 /* convert temperature and pressure */
+
+struct mpl115_data {
+ struct i2c_client *client;
+ struct mutex lock;
+ s16 a0;
+ s16 b1, b2;
+ s16 c12;
+};
+
+static int mpl115_request(struct mpl115_data *data)
+{
+ int ret = i2c_smbus_write_byte_data(data->client, MPL115_CONVERT, 0);
+ if (ret < 0)
+ return ret;
+
+ usleep_range(3000, 4000);
+
+ return 0;
+}
+
+static int mpl115_comp_pressure(struct mpl115_data *data, int *val, int *val2)
+{
+ int ret;
+ u16 padc, tadc;
+ int a1, y1, pcomp;
+ unsigned kpa;
+
+ mutex_lock(&data->lock);
+ ret = mpl115_request(data);
+ if (ret < 0)
+ goto done;
+
+ ret = i2c_smbus_read_word_swapped(data->client, MPL115_PADC);
+ if (ret < 0)
+ goto done;
+ padc = ret >> 6;
+
+ ret = i2c_smbus_read_word_swapped(data->client, MPL115_TADC);
+ if (ret < 0)
+ goto done;
+ tadc = ret >> 6;
+
+ /* see Freescale AN3785 */
+ a1 = data->b1 + ((data->c12 * tadc) >> 11);
+ y1 = (data->a0 << 10) + a1 * padc;
+
+ /* compensated pressure with 4 fractional bits */
+ pcomp = (y1 + ((data->b2 * (int) tadc) >> 1)) >> 9;
+
+ kpa = pcomp * (115 - 50) / 1023 + (50 << 4);
+ *val = kpa >> 4;
+ *val2 = (kpa & 15) * (1000000 >> 4);
+done:
+ mutex_unlock(&data->lock);
+ return ret;
+}
+
+static int mpl115_read_temp(struct mpl115_data *data)
+{
+ int ret;
+
+ mutex_lock(&data->lock);
+ ret = mpl115_request(data);
+ if (ret < 0)
+ goto done;
+ ret = i2c_smbus_read_word_swapped(data->client, MPL115_TADC);
+done:
+ mutex_unlock(&data->lock);
+ return ret;
+}
+
+static int mpl115_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct mpl115_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_PROCESSED:
+ ret = mpl115_comp_pressure(data, val, val2);
+ if (ret < 0)
+ return ret;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_RAW:
+ /* temperature -5.35 C / LSB, 472 LSB is 25 C */
+ ret = mpl115_read_temp(data);
+ if (ret < 0)
+ return ret;
+ *val = ret >> 6;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_OFFSET:
+ *val = 605;
+ *val2 = 750000;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SCALE:
+ *val = -186;
+ *val2 = 915888;
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+ return -EINVAL;
+}
+
+static const struct iio_chan_spec mpl115_channels[] = {
+ {
+ .type = IIO_PRESSURE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+ },
+ {
+ .type = IIO_TEMP,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE),
+ },
+};
+
+static const struct iio_info mpl115_info = {
+ .read_raw = &mpl115_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static int mpl115_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct mpl115_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
+ return -ENODEV;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ data->client = client;
+ mutex_init(&data->lock);
+
+ i2c_set_clientdata(client, indio_dev);
+ indio_dev->info = &mpl115_info;
+ indio_dev->name = id->name;
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = mpl115_channels;
+ indio_dev->num_channels = ARRAY_SIZE(mpl115_channels);
+
+ ret = i2c_smbus_read_word_swapped(data->client, MPL115_A0);
+ if (ret < 0)
+ return ret;
+ data->a0 = ret;
+ ret = i2c_smbus_read_word_swapped(data->client, MPL115_B1);
+ if (ret < 0)
+ return ret;
+ data->b1 = ret;
+ ret = i2c_smbus_read_word_swapped(data->client, MPL115_B2);
+ if (ret < 0)
+ return ret;
+ data->b2 = ret;
+ ret = i2c_smbus_read_word_swapped(data->client, MPL115_C12);
+ if (ret < 0)
+ return ret;
+ data->c12 = ret;
+
+ return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static const struct i2c_device_id mpl115_id[] = {
+ { "mpl115", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, mpl115_id);
+
+static struct i2c_driver mpl115_driver = {
+ .driver = {
+ .name = "mpl115",
+ },
+ .probe = mpl115_probe,
+ .id_table = mpl115_id,
+};
+module_i2c_driver(mpl115_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("Freescale MPL115 pressure/temperature driver");
+MODULE_LICENSE("GPL");
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/buffer.h>
-#include <linux/regulator/consumer.h>
#include <asm/unaligned.h>
#include <linux/iio/common/st_sensors.h>
#define ST_PRESS_TRIGGER_OPS NULL
#endif
-static void st_press_power_enable(struct iio_dev *indio_dev)
-{
- struct st_sensor_data *pdata = iio_priv(indio_dev);
- int err;
-
- /* Regulators not mandatory, but if requested we should enable them. */
- pdata->vdd = devm_regulator_get_optional(&indio_dev->dev, "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");
- }
-
- pdata->vdd_io = devm_regulator_get_optional(&indio_dev->dev, "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");
- }
-}
-
-static void st_press_power_disable(struct iio_dev *indio_dev)
-{
- struct st_sensor_data *pdata = iio_priv(indio_dev);
-
- if (!IS_ERR(pdata->vdd))
- regulator_disable(pdata->vdd);
-
- if (!IS_ERR(pdata->vdd_io))
- regulator_disable(pdata->vdd_io);
-}
-
int st_press_common_probe(struct iio_dev *indio_dev,
struct st_sensors_platform_data *plat_data)
{
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &press_info;
- st_press_power_enable(indio_dev);
+ st_sensors_power_enable(indio_dev);
err = st_sensors_check_device_support(indio_dev,
ARRAY_SIZE(st_press_sensors),
if (err)
goto st_press_device_register_error;
+ dev_info(&indio_dev->dev, "registered pressure sensor %s\n",
+ indio_dev->name);
+
return err;
st_press_device_register_error:
{
struct st_sensor_data *pdata = iio_priv(indio_dev);
- st_press_power_disable(indio_dev);
+ st_sensors_power_disable(indio_dev);
iio_device_unregister(indio_dev);
if (pdata->get_irq_data_ready(indio_dev) > 0)
--- /dev/null
+#
+# Proximity sensors
+#
+
+menu "Lightning sensors"
+
+config AS3935
+ tristate "AS3935 Franklin lightning sensor"
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ depends on SPI
+ help
+ Say Y here to build SPI interface support for the Austrian
+ Microsystems AS3935 lightning detection sensor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called as3935
+
+endmenu
--- /dev/null
+#
+# Makefile for IIO proximity sensors
+#
+
+# When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_AS3935) += as3935.o
--- /dev/null
+/*
+ * as3935.c - Support for AS3935 Franklin lightning sensor
+ *
+ * Copyright (C) 2014 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/interrupt.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.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/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/of_gpio.h>
+
+
+#define AS3935_AFE_GAIN 0x00
+#define AS3935_AFE_MASK 0x3F
+#define AS3935_AFE_GAIN_MAX 0x1F
+#define AS3935_AFE_PWR_BIT BIT(0)
+
+#define AS3935_INT 0x03
+#define AS3935_INT_MASK 0x07
+#define AS3935_EVENT_INT BIT(3)
+#define AS3935_NOISE_INT BIT(1)
+
+#define AS3935_DATA 0x07
+#define AS3935_DATA_MASK 0x3F
+
+#define AS3935_TUNE_CAP 0x08
+#define AS3935_CALIBRATE 0x3D
+
+#define AS3935_WRITE_DATA BIT(15)
+#define AS3935_READ_DATA BIT(14)
+#define AS3935_ADDRESS(x) ((x) << 8)
+
+#define MAX_PF_CAP 120
+#define TUNE_CAP_DIV 8
+
+struct as3935_state {
+ struct spi_device *spi;
+ struct iio_trigger *trig;
+ struct mutex lock;
+ struct delayed_work work;
+
+ u32 tune_cap;
+ u8 buf[2] ____cacheline_aligned;
+};
+
+static const struct iio_chan_spec as3935_channels[] = {
+ {
+ .type = IIO_PROXIMITY,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_PROCESSED),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 6,
+ .storagebits = 8,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(1),
+};
+
+static int as3935_read(struct as3935_state *st, unsigned int reg, int *val)
+{
+ u8 cmd;
+ int ret;
+
+ cmd = (AS3935_READ_DATA | AS3935_ADDRESS(reg)) >> 8;
+ ret = spi_w8r8(st->spi, cmd);
+ if (ret < 0)
+ return ret;
+ *val = ret;
+
+ return 0;
+};
+
+static int as3935_write(struct as3935_state *st,
+ unsigned int reg,
+ unsigned int val)
+{
+ u8 *buf = st->buf;
+
+ buf[0] = (AS3935_WRITE_DATA | AS3935_ADDRESS(reg)) >> 8;
+ buf[1] = val;
+
+ return spi_write(st->spi, buf, 2);
+};
+
+static ssize_t as3935_sensor_sensitivity_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct as3935_state *st = iio_priv(dev_to_iio_dev(dev));
+ int val, ret;
+
+ ret = as3935_read(st, AS3935_AFE_GAIN, &val);
+ if (ret)
+ return ret;
+ val = (val & AS3935_AFE_MASK) >> 1;
+
+ return sprintf(buf, "%d\n", val);
+};
+
+static ssize_t as3935_sensor_sensitivity_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct as3935_state *st = iio_priv(dev_to_iio_dev(dev));
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul((const char *) buf, 10, &val);
+ if (ret)
+ return -EINVAL;
+
+ if (val > AS3935_AFE_GAIN_MAX)
+ return -EINVAL;
+
+ as3935_write(st, AS3935_AFE_GAIN, val << 1);
+
+ return len;
+};
+
+static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
+ as3935_sensor_sensitivity_show, as3935_sensor_sensitivity_store, 0);
+
+
+static struct attribute *as3935_attributes[] = {
+ &iio_dev_attr_sensor_sensitivity.dev_attr.attr,
+ NULL,
+};
+
+static struct attribute_group as3935_attribute_group = {
+ .attrs = as3935_attributes,
+};
+
+static int as3935_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long m)
+{
+ struct as3935_state *st = iio_priv(indio_dev);
+ int ret;
+
+
+ switch (m) {
+ case IIO_CHAN_INFO_PROCESSED:
+ case IIO_CHAN_INFO_RAW:
+ *val2 = 0;
+ ret = as3935_read(st, AS3935_DATA, val);
+ if (ret)
+ return ret;
+
+ if (m == IIO_CHAN_INFO_RAW)
+ return IIO_VAL_INT;
+
+ /* storm out of range */
+ if (*val == AS3935_DATA_MASK)
+ return -EINVAL;
+ *val *= 1000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return IIO_VAL_INT;
+}
+
+static const struct iio_info as3935_info = {
+ .driver_module = THIS_MODULE,
+ .attrs = &as3935_attribute_group,
+ .read_raw = &as3935_read_raw,
+};
+
+static irqreturn_t as3935_trigger_handler(int irq, void *private)
+{
+ struct iio_poll_func *pf = private;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct as3935_state *st = iio_priv(indio_dev);
+ int val, ret;
+
+ ret = as3935_read(st, AS3935_DATA, &val);
+ if (ret)
+ goto err_read;
+ val &= AS3935_DATA_MASK;
+ val *= 1000;
+
+ iio_push_to_buffers_with_timestamp(indio_dev, &val, pf->timestamp);
+err_read:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+};
+
+static const struct iio_trigger_ops iio_interrupt_trigger_ops = {
+ .owner = THIS_MODULE,
+};
+
+static void as3935_event_work(struct work_struct *work)
+{
+ struct as3935_state *st;
+ int val;
+
+ st = container_of(work, struct as3935_state, work.work);
+
+ as3935_read(st, AS3935_INT, &val);
+ val &= AS3935_INT_MASK;
+
+ switch (val) {
+ case AS3935_EVENT_INT:
+ iio_trigger_poll(st->trig, iio_get_time_ns());
+ break;
+ case AS3935_NOISE_INT:
+ dev_warn(&st->spi->dev, "noise level is too high");
+ break;
+ }
+};
+
+static irqreturn_t as3935_interrupt_handler(int irq, void *private)
+{
+ struct iio_dev *indio_dev = private;
+ struct as3935_state *st = iio_priv(indio_dev);
+
+ /*
+ * Delay work for >2 milliseconds after an interrupt to allow
+ * estimated distance to recalculated.
+ */
+
+ schedule_delayed_work(&st->work, msecs_to_jiffies(3));
+
+ return IRQ_HANDLED;
+}
+
+static void calibrate_as3935(struct as3935_state *st)
+{
+ mutex_lock(&st->lock);
+
+ /* mask disturber interrupt bit */
+ as3935_write(st, AS3935_INT, BIT(5));
+
+ as3935_write(st, AS3935_CALIBRATE, 0x96);
+ as3935_write(st, AS3935_TUNE_CAP,
+ BIT(5) | (st->tune_cap / TUNE_CAP_DIV));
+
+ mdelay(2);
+ as3935_write(st, AS3935_TUNE_CAP, (st->tune_cap / TUNE_CAP_DIV));
+
+ mutex_unlock(&st->lock);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int as3935_suspend(struct spi_device *spi, pm_message_t msg)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct as3935_state *st = iio_priv(indio_dev);
+ int val, ret;
+
+ mutex_lock(&st->lock);
+ ret = as3935_read(st, AS3935_AFE_GAIN, &val);
+ if (ret)
+ goto err_suspend;
+ val |= AS3935_AFE_PWR_BIT;
+
+ ret = as3935_write(st, AS3935_AFE_GAIN, val);
+
+err_suspend:
+ mutex_unlock(&st->lock);
+
+ return ret;
+}
+
+static int as3935_resume(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct as3935_state *st = iio_priv(indio_dev);
+ int val, ret;
+
+ mutex_lock(&st->lock);
+ ret = as3935_read(st, AS3935_AFE_GAIN, &val);
+ if (ret)
+ goto err_resume;
+ val &= ~AS3935_AFE_PWR_BIT;
+ ret = as3935_write(st, AS3935_AFE_GAIN, val);
+
+err_resume:
+ mutex_unlock(&st->lock);
+
+ return ret;
+}
+#else
+#define as3935_suspend NULL
+#define as3935_resume NULL
+#endif
+
+static int as3935_probe(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev;
+ struct iio_trigger *trig;
+ struct as3935_state *st;
+ struct device_node *np = spi->dev.of_node;
+ int ret;
+
+ /* Be sure lightning event interrupt is specified */
+ if (!spi->irq) {
+ dev_err(&spi->dev, "unable to get event interrupt\n");
+ return -EINVAL;
+ }
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(st));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+ st->spi = spi;
+ st->tune_cap = 0;
+
+ spi_set_drvdata(spi, indio_dev);
+ mutex_init(&st->lock);
+ INIT_DELAYED_WORK(&st->work, as3935_event_work);
+
+ ret = of_property_read_u32(np,
+ "ams,tuning-capacitor-pf", &st->tune_cap);
+ if (ret) {
+ st->tune_cap = 0;
+ dev_warn(&spi->dev,
+ "no tuning-capacitor-pf set, defaulting to %d",
+ st->tune_cap);
+ }
+
+ if (st->tune_cap > MAX_PF_CAP) {
+ dev_err(&spi->dev,
+ "wrong tuning-capacitor-pf setting of %d\n",
+ st->tune_cap);
+ return -EINVAL;
+ }
+
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->channels = as3935_channels;
+ indio_dev->num_channels = ARRAY_SIZE(as3935_channels);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &as3935_info;
+
+ trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d",
+ indio_dev->name, indio_dev->id);
+
+ if (!trig)
+ return -ENOMEM;
+
+ st->trig = trig;
+ trig->dev.parent = indio_dev->dev.parent;
+ iio_trigger_set_drvdata(trig, indio_dev);
+ trig->ops = &iio_interrupt_trigger_ops;
+
+ ret = iio_trigger_register(trig);
+ if (ret) {
+ dev_err(&spi->dev, "failed to register trigger\n");
+ return ret;
+ }
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ &as3935_trigger_handler, NULL);
+
+ if (ret) {
+ dev_err(&spi->dev, "cannot setup iio trigger\n");
+ goto unregister_trigger;
+ }
+
+ calibrate_as3935(st);
+
+ ret = devm_request_irq(&spi->dev, spi->irq,
+ &as3935_interrupt_handler,
+ IRQF_TRIGGER_RISING,
+ dev_name(&spi->dev),
+ indio_dev);
+
+ if (ret) {
+ dev_err(&spi->dev, "unable to request irq\n");
+ goto unregister_buffer;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&spi->dev, "unable to register device\n");
+ goto unregister_buffer;
+ }
+ return 0;
+
+unregister_buffer:
+ iio_triggered_buffer_cleanup(indio_dev);
+
+unregister_trigger:
+ iio_trigger_unregister(st->trig);
+
+ return ret;
+};
+
+static int as3935_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct as3935_state *st = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+ iio_trigger_unregister(st->trig);
+
+ return 0;
+};
+
+static const struct spi_device_id as3935_id[] = {
+ {"as3935", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(spi, as3935_id);
+
+static struct spi_driver as3935_driver = {
+ .driver = {
+ .name = "as3935",
+ .owner = THIS_MODULE,
+ },
+ .probe = as3935_probe,
+ .remove = as3935_remove,
+ .id_table = as3935_id,
+ .suspend = as3935_suspend,
+ .resume = as3935_resume,
+};
+module_spi_driver(as3935_driver);
+
+MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>");
+MODULE_DESCRIPTION("AS3935 lightning sensor");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:as3935");
#
menu "Temperature sensors"
+config MLX90614
+ tristate "MLX90614 contact-less infrared sensor"
+ depends on I2C
+ help
+ If you say yes here you get support for the Melexis
+ MLX90614 contact-less infrared sensor connected with I2C.
+
+ This driver can also be built as a module. If so, the module will
+ be called mlx90614.
+
config TMP006
tristate "TMP006 infrared thermopile sensor"
depends on I2C
# Makefile for industrial I/O temperature drivers
#
+obj-$(CONFIG_MLX90614) += mlx90614.o
obj-$(CONFIG_TMP006) += tmp006.o
--- /dev/null
+/*
+ * mlx90614.c - Support for Melexis MLX90614 contactless IR temperature sensor
+ *
+ * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * 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.
+ *
+ * Driver for the Melexis MLX90614 I2C 16-bit IR thermopile sensor
+ *
+ * (7-bit I2C slave address 0x5a, 100KHz bus speed only!)
+ *
+ * TODO: sleep mode, configuration EEPROM
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+
+#define MLX90614_OP_RAM 0x00
+
+/* RAM offsets with 16-bit data, MSB first */
+#define MLX90614_TA 0x06 /* ambient temperature */
+#define MLX90614_TOBJ1 0x07 /* object temperature */
+
+struct mlx90614_data {
+ struct i2c_client *client;
+};
+
+static int mlx90614_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *channel, int *val,
+ int *val2, long mask)
+{
+ struct mlx90614_data *data = iio_priv(indio_dev);
+ s32 ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW: /* 0.02K / LSB */
+ switch (channel->channel2) {
+ case IIO_MOD_TEMP_AMBIENT:
+ ret = i2c_smbus_read_word_data(data->client,
+ MLX90614_OP_RAM | MLX90614_TA);
+ if (ret < 0)
+ return ret;
+ break;
+ case IIO_MOD_TEMP_OBJECT:
+ ret = i2c_smbus_read_word_data(data->client,
+ MLX90614_OP_RAM | MLX90614_TOBJ1);
+ if (ret < 0)
+ return ret;
+ break;
+ default:
+ return -EINVAL;
+ }
+ *val = ret;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_OFFSET:
+ *val = 13657;
+ *val2 = 500000;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 20;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_chan_spec mlx90614_channels[] = {
+ {
+ .type = IIO_TEMP,
+ .modified = 1,
+ .channel2 = IIO_MOD_TEMP_AMBIENT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ },
+ {
+ .type = IIO_TEMP,
+ .modified = 1,
+ .channel2 = IIO_MOD_TEMP_OBJECT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ },
+};
+
+static const struct iio_info mlx90614_info = {
+ .read_raw = mlx90614_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static int mlx90614_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct iio_dev *indio_dev;
+ struct mlx90614_data *data;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
+ return -ENODEV;
+
+ 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->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &mlx90614_info;
+
+ indio_dev->channels = mlx90614_channels;
+ indio_dev->num_channels = ARRAY_SIZE(mlx90614_channels);
+
+ return iio_device_register(indio_dev);
+}
+
+static int mlx90614_remove(struct i2c_client *client)
+{
+ iio_device_unregister(i2c_get_clientdata(client));
+
+ return 0;
+}
+
+static const struct i2c_device_id mlx90614_id[] = {
+ { "mlx90614", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, mlx90614_id);
+
+static struct i2c_driver mlx90614_driver = {
+ .driver = {
+ .name = "mlx90614",
+ .owner = THIS_MODULE,
+ },
+ .probe = mlx90614_probe,
+ .remove = mlx90614_remove,
+ .id_table = mlx90614_id,
+};
+module_i2c_driver(mlx90614_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("Melexis MLX90614 contactless IR temperature sensor driver");
+MODULE_LICENSE("GPL");
add_timer(&ep->timer);
}
-static void stop_ep_timer(struct c4iw_ep *ep)
+static int stop_ep_timer(struct c4iw_ep *ep)
{
PDBG("%s ep %p stopping\n", __func__, ep);
del_timer_sync(&ep->timer);
- if (!test_and_set_bit(TIMEOUT, &ep->com.flags))
+ if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) {
c4iw_put_ep(&ep->com);
+ return 0;
+ }
+ return 1;
}
static int c4iw_l2t_send(struct c4iw_rdev *rdev, struct sk_buff *skb,
PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
/*
- * Stop mpa timer. If it expired, then the state has
- * changed and we bail since ep_timeout already aborted
- * the connection.
+ * Stop mpa timer. If it expired, then
+ * we ignore the MPA reply. process_timeout()
+ * will abort the connection.
*/
- stop_ep_timer(ep);
- if (ep->com.state != MPA_REQ_SENT)
+ if (stop_ep_timer(ep))
return;
/*
PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
- if (ep->com.state != MPA_REQ_WAIT)
- return;
-
/*
* If we get more than the supported amount of private data
* then we must fail this connection.
*/
if (ep->mpa_pkt_len + skb->len > sizeof(ep->mpa_pkt)) {
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
abort_connection(ep, skb, GFP_KERNEL);
return;
}
if (mpa->revision > mpa_rev) {
printk(KERN_ERR MOD "%s MPA version mismatch. Local = %d,"
" Received = %d\n", __func__, mpa_rev, mpa->revision);
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
abort_connection(ep, skb, GFP_KERNEL);
return;
}
if (memcmp(mpa->key, MPA_KEY_REQ, sizeof(mpa->key))) {
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
abort_connection(ep, skb, GFP_KERNEL);
return;
}
* Fail if there's too much private data.
*/
if (plen > MPA_MAX_PRIVATE_DATA) {
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
abort_connection(ep, skb, GFP_KERNEL);
return;
}
* If plen does not account for pkt size
*/
if (ep->mpa_pkt_len > (sizeof(*mpa) + plen)) {
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
abort_connection(ep, skb, GFP_KERNEL);
return;
}
ep->mpa_attr.xmit_marker_enabled, ep->mpa_attr.version,
ep->mpa_attr.p2p_type);
- __state_set(&ep->com, MPA_REQ_RCVD);
- stop_ep_timer(ep);
-
- /* drive upcall */
- mutex_lock(&ep->parent_ep->com.mutex);
- if (ep->parent_ep->com.state != DEAD) {
- if (connect_request_upcall(ep))
+ /*
+ * If the endpoint timer already expired, then we ignore
+ * the start request. process_timeout() will abort
+ * the connection.
+ */
+ if (!stop_ep_timer(ep)) {
+ __state_set(&ep->com, MPA_REQ_RCVD);
+
+ /* drive upcall */
+ mutex_lock(&ep->parent_ep->com.mutex);
+ if (ep->parent_ep->com.state != DEAD) {
+ if (connect_request_upcall(ep))
+ abort_connection(ep, skb, GFP_KERNEL);
+ } else {
abort_connection(ep, skb, GFP_KERNEL);
- } else {
- abort_connection(ep, skb, GFP_KERNEL);
+ }
+ mutex_unlock(&ep->parent_ep->com.mutex);
}
- mutex_unlock(&ep->parent_ep->com.mutex);
return;
}
disconnect = 0;
break;
case MORIBUND:
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
if (ep->com.cm_id && ep->com.qp) {
attrs.next_state = C4IW_QP_STATE_IDLE;
c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
case CONNECTING:
break;
case MPA_REQ_WAIT:
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
break;
case MPA_REQ_SENT:
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
if (mpa_rev == 1 || (mpa_rev == 2 && ep->tried_with_mpa_v1))
connect_reply_upcall(ep, -ECONNRESET);
else {
__state_set(&ep->com, MORIBUND);
break;
case MORIBUND:
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
if ((ep->com.cm_id) && (ep->com.qp)) {
attrs.next_state = C4IW_QP_STATE_IDLE;
c4iw_modify_qp(ep->com.qp->rhp,
if (!test_and_set_bit(CLOSE_SENT, &ep->com.flags)) {
close = 1;
if (abrupt) {
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
ep->com.state = ABORTING;
} else
ep->com.state = MORIBUND;
__state_set(&ep->com, ABORTING);
close_complete_upcall(ep, -ETIMEDOUT);
break;
+ case ABORTING:
+ case DEAD:
+
+ /*
+ * These states are expected if the ep timed out at the same
+ * time as another thread was calling stop_ep_timer().
+ * So we silently do nothing for these states.
+ */
+ abort = 0;
+ break;
default:
WARN(1, "%s unexpected state ep %p tid %u state %u\n",
__func__, ep, ep->hwtid, ep->com.state);
tmp = timeout_list.next;
list_del(tmp);
+ tmp->next = NULL;
+ tmp->prev = NULL;
spin_unlock_irq(&timeout_lock);
ep = list_entry(tmp, struct c4iw_ep, entry);
process_timeout(ep);
unsigned int opcode;
int ret;
+ process_timedout_eps();
while ((skb = skb_dequeue(&rxq))) {
rpl = cplhdr(skb);
dev = *((struct c4iw_dev **) (skb->cb + sizeof(void *)));
ret = work_handlers[opcode](dev, skb);
if (!ret)
kfree_skb(skb);
+ process_timedout_eps();
}
- process_timedout_eps();
}
static DECLARE_WORK(skb_work, process_work);
spin_lock(&timeout_lock);
if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) {
- list_add_tail(&ep->entry, &timeout_list);
- kickit = 1;
+ /*
+ * Only insert if it is not already on the list.
+ */
+ if (!ep->entry.next) {
+ list_add_tail(&ep->entry, &timeout_list);
+ kickit = 1;
+ }
}
spin_unlock(&timeout_lock);
if (kickit)
struct t4_cq *cq = &chp->cq;
int idx;
struct t4_swsqe *swsqe;
- int error = (qhp->attr.state != C4IW_QP_STATE_CLOSING &&
- qhp->attr.state != C4IW_QP_STATE_IDLE);
if (wq->sq.flush_cidx == -1)
wq->sq.flush_cidx = wq->sq.cidx;
idx = wq->sq.flush_cidx;
BUG_ON(idx >= wq->sq.size);
while (idx != wq->sq.pidx) {
- if (error) {
- swsqe = &wq->sq.sw_sq[idx];
- BUG_ON(swsqe->flushed);
- swsqe->flushed = 1;
- insert_sq_cqe(wq, cq, swsqe);
- if (wq->sq.oldest_read == swsqe) {
- BUG_ON(swsqe->opcode != FW_RI_READ_REQ);
- advance_oldest_read(wq);
- }
- flushed++;
- } else {
- t4_sq_consume(wq);
+ swsqe = &wq->sq.sw_sq[idx];
+ BUG_ON(swsqe->flushed);
+ swsqe->flushed = 1;
+ insert_sq_cqe(wq, cq, swsqe);
+ if (wq->sq.oldest_read == swsqe) {
+ BUG_ON(swsqe->opcode != FW_RI_READ_REQ);
+ advance_oldest_read(wq);
}
+ flushed++;
if (++idx == wq->sq.size)
idx = 0;
}
static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc)
{
struct c4iw_qp *qhp = NULL;
- struct t4_cqe cqe = {0, 0}, *rd_cqe;
+ struct t4_cqe uninitialized_var(cqe), *rd_cqe;
struct t4_wq *wq;
u32 credit = 0;
u8 cqe_flushed;
idr_destroy(&ctx->dev->hwtid_idr);
idr_destroy(&ctx->dev->stid_idr);
idr_destroy(&ctx->dev->atid_idr);
- iounmap(ctx->dev->rdev.oc_mw_kva);
+ if (ctx->dev->rdev.bar2_kva)
+ iounmap(ctx->dev->rdev.bar2_kva);
+ if (ctx->dev->rdev.oc_mw_kva)
+ iounmap(ctx->dev->rdev.oc_mw_kva);
ib_dealloc_device(&ctx->dev->ibdev);
ctx->dev = NULL;
}
}
devp->rdev.lldi = *infop;
- devp->rdev.oc_mw_pa = pci_resource_start(devp->rdev.lldi.pdev, 2) +
- (pci_resource_len(devp->rdev.lldi.pdev, 2) -
- roundup_pow_of_two(devp->rdev.lldi.vr->ocq.size));
- devp->rdev.oc_mw_kva = ioremap_wc(devp->rdev.oc_mw_pa,
- devp->rdev.lldi.vr->ocq.size);
+ /*
+ * For T5 devices, we map all of BAR2 with WC.
+ * For T4 devices with onchip qp mem, we map only that part
+ * of BAR2 with WC.
+ */
+ devp->rdev.bar2_pa = pci_resource_start(devp->rdev.lldi.pdev, 2);
+ if (is_t5(devp->rdev.lldi.adapter_type)) {
+ devp->rdev.bar2_kva = ioremap_wc(devp->rdev.bar2_pa,
+ pci_resource_len(devp->rdev.lldi.pdev, 2));
+ if (!devp->rdev.bar2_kva) {
+ pr_err(MOD "Unable to ioremap BAR2\n");
+ return ERR_PTR(-EINVAL);
+ }
+ } else if (ocqp_supported(infop)) {
+ devp->rdev.oc_mw_pa =
+ pci_resource_start(devp->rdev.lldi.pdev, 2) +
+ pci_resource_len(devp->rdev.lldi.pdev, 2) -
+ roundup_pow_of_two(devp->rdev.lldi.vr->ocq.size);
+ devp->rdev.oc_mw_kva = ioremap_wc(devp->rdev.oc_mw_pa,
+ devp->rdev.lldi.vr->ocq.size);
+ if (!devp->rdev.oc_mw_kva) {
+ pr_err(MOD "Unable to ioremap onchip mem\n");
+ return ERR_PTR(-EINVAL);
+ }
+ }
PDBG(KERN_INFO MOD "ocq memory: "
"hw_start 0x%x size %u mw_pa 0x%lx mw_kva %p\n",
static void resume_rc_qp(struct c4iw_qp *qp)
{
spin_lock(&qp->lock);
- t4_ring_sq_db(&qp->wq, qp->wq.sq.wq_pidx_inc);
+ t4_ring_sq_db(&qp->wq, qp->wq.sq.wq_pidx_inc,
+ is_t5(qp->rhp->rdev.lldi.adapter_type), NULL);
qp->wq.sq.wq_pidx_inc = 0;
- t4_ring_rq_db(&qp->wq, qp->wq.rq.wq_pidx_inc);
+ t4_ring_rq_db(&qp->wq, qp->wq.rq.wq_pidx_inc,
+ is_t5(qp->rhp->rdev.lldi.adapter_type), NULL);
qp->wq.rq.wq_pidx_inc = 0;
spin_unlock(&qp->lock);
}
struct gen_pool *ocqp_pool;
u32 flags;
struct cxgb4_lld_info lldi;
+ unsigned long bar2_pa;
+ void __iomem *bar2_kva;
unsigned long oc_mw_pa;
void __iomem *oc_mw_kva;
struct c4iw_stats stats;
if ((!reset_tpt_entry) && (*stag == T4_STAG_UNSET)) {
stag_idx = c4iw_get_resource(&rdev->resource.tpt_table);
- if (!stag_idx)
+ if (!stag_idx) {
+ mutex_lock(&rdev->stats.lock);
+ rdev->stats.stag.fail++;
+ mutex_unlock(&rdev->stats.lock);
return -ENOMEM;
+ }
mutex_lock(&rdev->stats.lock);
rdev->stats.stag.cur += 32;
if (rdev->stats.stag.cur > rdev->stats.stag.max)
props->max_mr = c4iw_num_stags(&dev->rdev);
props->max_pd = T4_MAX_NUM_PD;
props->local_ca_ack_delay = 0;
- props->max_fast_reg_page_list_len = T4_MAX_FR_DEPTH;
+ props->max_fast_reg_page_list_len = t4_max_fr_depth(use_dsgl);
return 0;
}
wq->db = rdev->lldi.db_reg;
wq->gts = rdev->lldi.gts_reg;
- if (user) {
- wq->sq.udb = (u64)pci_resource_start(rdev->lldi.pdev, 2) +
- (wq->sq.qid << rdev->qpshift);
- wq->sq.udb &= PAGE_MASK;
- wq->rq.udb = (u64)pci_resource_start(rdev->lldi.pdev, 2) +
- (wq->rq.qid << rdev->qpshift);
- wq->rq.udb &= PAGE_MASK;
+ if (user || is_t5(rdev->lldi.adapter_type)) {
+ u32 off;
+
+ off = (wq->sq.qid << rdev->qpshift) & PAGE_MASK;
+ if (user) {
+ wq->sq.udb = (u64 __iomem *)(rdev->bar2_pa + off);
+ } else {
+ off += 128 * (wq->sq.qid & rdev->qpmask) + 8;
+ wq->sq.udb = (u64 __iomem *)(rdev->bar2_kva + off);
+ }
+ off = (wq->rq.qid << rdev->qpshift) & PAGE_MASK;
+ if (user) {
+ wq->rq.udb = (u64 __iomem *)(rdev->bar2_pa + off);
+ } else {
+ off += 128 * (wq->rq.qid & rdev->qpmask) + 8;
+ wq->rq.udb = (u64 __iomem *)(rdev->bar2_kva + off);
+ }
}
wq->rdev = rdev;
wq->rq.msn = 1;
if (ret)
goto free_dma;
- PDBG("%s sqid 0x%x rqid 0x%x kdb 0x%p squdb 0x%llx rqudb 0x%llx\n",
+ PDBG("%s sqid 0x%x rqid 0x%x kdb 0x%p squdb 0x%lx rqudb 0x%lx\n",
__func__, wq->sq.qid, wq->rq.qid, wq->db,
- (unsigned long long)wq->sq.udb, (unsigned long long)wq->rq.udb);
+ (__force unsigned long) wq->sq.udb,
+ (__force unsigned long) wq->rq.udb);
return 0;
free_dma:
default:
return -EINVAL;
}
+ wqe->send.r3 = 0;
+ wqe->send.r4 = 0;
plen = 0;
if (wr->num_sge) {
int pbllen = roundup(wr->wr.fast_reg.page_list_len * sizeof(u64), 32);
int rem;
- if (wr->wr.fast_reg.page_list_len > T4_MAX_FR_DEPTH)
+ if (wr->wr.fast_reg.page_list_len >
+ t4_max_fr_depth(use_dsgl))
return -EINVAL;
wqe->fr.qpbinde_to_dcacpu = 0;
spin_lock_irqsave(&qhp->rhp->lock, flags);
spin_lock(&qhp->lock);
- if (qhp->rhp->db_state == NORMAL) {
- t4_ring_sq_db(&qhp->wq, inc);
- } else {
+ if (qhp->rhp->db_state == NORMAL)
+ t4_ring_sq_db(&qhp->wq, inc,
+ is_t5(qhp->rhp->rdev.lldi.adapter_type), NULL);
+ else {
add_to_fc_list(&qhp->rhp->db_fc_list, &qhp->db_fc_entry);
qhp->wq.sq.wq_pidx_inc += inc;
}
spin_lock_irqsave(&qhp->rhp->lock, flags);
spin_lock(&qhp->lock);
- if (qhp->rhp->db_state == NORMAL) {
- t4_ring_rq_db(&qhp->wq, inc);
- } else {
+ if (qhp->rhp->db_state == NORMAL)
+ t4_ring_rq_db(&qhp->wq, inc,
+ is_t5(qhp->rhp->rdev.lldi.adapter_type), NULL);
+ else {
add_to_fc_list(&qhp->rhp->db_fc_list, &qhp->db_fc_entry);
qhp->wq.rq.wq_pidx_inc += inc;
}
enum fw_wr_opcodes fw_opcode = 0;
enum fw_ri_wr_flags fw_flags;
struct c4iw_qp *qhp;
- union t4_wr *wqe;
+ union t4_wr *wqe = NULL;
u32 num_wrs;
struct t4_swsqe *swsqe;
unsigned long flag;
idx += DIV_ROUND_UP(len16*16, T4_EQ_ENTRY_SIZE);
}
if (!qhp->rhp->rdev.status_page->db_off) {
- t4_ring_sq_db(&qhp->wq, idx);
+ t4_ring_sq_db(&qhp->wq, idx,
+ is_t5(qhp->rhp->rdev.lldi.adapter_type), wqe);
spin_unlock_irqrestore(&qhp->lock, flag);
} else {
spin_unlock_irqrestore(&qhp->lock, flag);
{
int err = 0;
struct c4iw_qp *qhp;
- union t4_recv_wr *wqe;
+ union t4_recv_wr *wqe = NULL;
u32 num_wrs;
u8 len16 = 0;
unsigned long flag;
num_wrs--;
}
if (!qhp->rhp->rdev.status_page->db_off) {
- t4_ring_rq_db(&qhp->wq, idx);
+ t4_ring_rq_db(&qhp->wq, idx,
+ is_t5(qhp->rhp->rdev.lldi.adapter_type), wqe);
spin_unlock_irqrestore(&qhp->lock, flag);
} else {
spin_unlock_irqrestore(&qhp->lock, flag);
switch (attrs->next_state) {
case C4IW_QP_STATE_CLOSING:
BUG_ON(atomic_read(&qhp->ep->com.kref.refcount) < 2);
+ t4_set_wq_in_error(&qhp->wq);
set_state(qhp, C4IW_QP_STATE_CLOSING);
ep = qhp->ep;
if (!internal) {
disconnect = 1;
c4iw_get_ep(&qhp->ep->com);
}
- t4_set_wq_in_error(&qhp->wq);
ret = rdma_fini(rhp, qhp, ep);
if (ret)
goto err;
break;
case C4IW_QP_STATE_TERMINATE:
+ t4_set_wq_in_error(&qhp->wq);
set_state(qhp, C4IW_QP_STATE_TERMINATE);
qhp->attr.layer_etype = attrs->layer_etype;
qhp->attr.ecode = attrs->ecode;
- t4_set_wq_in_error(&qhp->wq);
ep = qhp->ep;
disconnect = 1;
+ c4iw_get_ep(&qhp->ep->com);
if (!internal)
terminate = 1;
else {
if (ret)
goto err;
}
- c4iw_get_ep(&qhp->ep->com);
break;
case C4IW_QP_STATE_ERROR:
- set_state(qhp, C4IW_QP_STATE_ERROR);
t4_set_wq_in_error(&qhp->wq);
+ set_state(qhp, C4IW_QP_STATE_ERROR);
if (!internal) {
abort = 1;
disconnect = 1;
mm2->len = PAGE_ALIGN(qhp->wq.rq.memsize);
insert_mmap(ucontext, mm2);
mm3->key = uresp.sq_db_gts_key;
- mm3->addr = qhp->wq.sq.udb;
+ mm3->addr = (__force unsigned long) qhp->wq.sq.udb;
mm3->len = PAGE_SIZE;
insert_mmap(ucontext, mm3);
mm4->key = uresp.rq_db_gts_key;
- mm4->addr = qhp->wq.rq.udb;
+ mm4->addr = (__force unsigned long) qhp->wq.rq.udb;
mm4->len = PAGE_SIZE;
insert_mmap(ucontext, mm4);
if (mm5) {
kfree(entry);
} else {
qid = c4iw_get_resource(&rdev->resource.qid_table);
- if (!qid)
+ if (!qid) {
+ mutex_lock(&rdev->stats.lock);
+ rdev->stats.qid.fail++;
+ mutex_unlock(&rdev->stats.lock);
goto out;
+ }
mutex_lock(&rdev->stats.lock);
rdev->stats.qid.cur += rdev->qpmask + 1;
mutex_unlock(&rdev->stats.lock);
unsigned long addr = gen_pool_alloc(rdev->rqt_pool, size << 6);
PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size << 6);
if (!addr)
- printk_ratelimited(KERN_WARNING MOD "%s: Out of RQT memory\n",
- pci_name(rdev->lldi.pdev));
+ pr_warn_ratelimited(MOD "%s: Out of RQT memory\n",
+ pci_name(rdev->lldi.pdev));
mutex_lock(&rdev->stats.lock);
if (addr) {
rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT);
sizeof(struct fw_ri_isgl)) / sizeof(struct fw_ri_sge))
#define T4_MAX_FR_IMMD ((T4_SQ_NUM_BYTES - sizeof(struct fw_ri_fr_nsmr_wr) - \
sizeof(struct fw_ri_immd)) & ~31UL)
-#define T4_MAX_FR_DEPTH (1024 / sizeof(u64))
+#define T4_MAX_FR_IMMD_DEPTH (T4_MAX_FR_IMMD / sizeof(u64))
+#define T4_MAX_FR_DSGL 1024
+#define T4_MAX_FR_DSGL_DEPTH (T4_MAX_FR_DSGL / sizeof(u64))
+
+static inline int t4_max_fr_depth(int use_dsgl)
+{
+ return use_dsgl ? T4_MAX_FR_DSGL_DEPTH : T4_MAX_FR_IMMD_DEPTH;
+}
#define T4_RQ_NUM_SLOTS 2
#define T4_RQ_NUM_BYTES (T4_EQ_ENTRY_SIZE * T4_RQ_NUM_SLOTS)
unsigned long phys_addr;
struct t4_swsqe *sw_sq;
struct t4_swsqe *oldest_read;
- u64 udb;
+ u64 __iomem *udb;
size_t memsize;
u32 qid;
u16 in_use;
dma_addr_t dma_addr;
DEFINE_DMA_UNMAP_ADDR(mapping);
struct t4_swrqe *sw_rq;
- u64 udb;
+ u64 __iomem *udb;
size_t memsize;
u32 qid;
u32 msn;
return wq->sq.size * T4_SQ_NUM_SLOTS;
}
-static inline void t4_ring_sq_db(struct t4_wq *wq, u16 inc)
+/* This function copies 64 byte coalesced work request to memory
+ * mapped BAR2 space. For coalesced WRs, the SGE fetches data
+ * from the FIFO instead of from Host.
+ */
+static inline void pio_copy(u64 __iomem *dst, u64 *src)
+{
+ int count = 8;
+
+ while (count) {
+ writeq(*src, dst);
+ src++;
+ dst++;
+ count--;
+ }
+}
+
+static inline void t4_ring_sq_db(struct t4_wq *wq, u16 inc, u8 t5,
+ union t4_wr *wqe)
{
+
+ /* Flush host queue memory writes. */
wmb();
+ if (t5) {
+ if (inc == 1 && wqe) {
+ PDBG("%s: WC wq->sq.pidx = %d\n",
+ __func__, wq->sq.pidx);
+ pio_copy(wq->sq.udb + 7, (void *)wqe);
+ } else {
+ PDBG("%s: DB wq->sq.pidx = %d\n",
+ __func__, wq->sq.pidx);
+ writel(PIDX_T5(inc), wq->sq.udb);
+ }
+
+ /* Flush user doorbell area writes. */
+ wmb();
+ return;
+ }
writel(QID(wq->sq.qid) | PIDX(inc), wq->db);
}
-static inline void t4_ring_rq_db(struct t4_wq *wq, u16 inc)
+static inline void t4_ring_rq_db(struct t4_wq *wq, u16 inc, u8 t5,
+ union t4_recv_wr *wqe)
{
+
+ /* Flush host queue memory writes. */
wmb();
+ if (t5) {
+ if (inc == 1 && wqe) {
+ PDBG("%s: WC wq->rq.pidx = %d\n",
+ __func__, wq->rq.pidx);
+ pio_copy(wq->rq.udb + 7, (void *)wqe);
+ } else {
+ PDBG("%s: DB wq->rq.pidx = %d\n",
+ __func__, wq->rq.pidx);
+ writel(PIDX_T5(inc), wq->rq.udb);
+ }
+
+ /* Flush user doorbell area writes. */
+ wmb();
+ return;
+ }
writel(QID(wq->rq.qid) | PIDX(inc), wq->db);
}
printk(KERN_ERR MOD "cq overflow cqid %u\n", cq->cqid);
BUG_ON(1);
} else if (t4_valid_cqe(cq, &cq->queue[cq->cidx])) {
+
+ /* Ensure CQE is flushed to memory */
+ rmb();
*cqe = &cq->queue[cq->cidx];
ret = 0;
} else
props->sig_guard_cap = IB_GUARD_T10DIF_CRC |
IB_GUARD_T10DIF_CSUM;
}
+ if (flags & MLX5_DEV_CAP_FLAG_BLOCK_MCAST)
+ props->device_cap_flags |= IB_DEVICE_BLOCK_MULTICAST_LOOPBACK;
props->vendor_id = be32_to_cpup((__be32 *)(out_mad->data + 36)) &
0xffffff;
spin_lock_init(&qp->sq.lock);
spin_lock_init(&qp->rq.lock);
+ if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) {
+ if (!(dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_BLOCK_MCAST)) {
+ mlx5_ib_dbg(dev, "block multicast loopback isn't supported\n");
+ return -EINVAL;
+ } else {
+ qp->flags |= MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK;
+ }
+ }
+
if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE;
if (qp->wq_sig)
in->ctx.flags_pd |= cpu_to_be32(MLX5_QP_ENABLE_SIG);
+ if (qp->flags & MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK)
+ in->ctx.flags_pd |= cpu_to_be32(MLX5_QP_BLOCK_MCAST);
+
if (qp->scat_cqe && is_connected(init_attr->qp_type)) {
int rcqe_sz;
int scqe_sz;
entries[1].entry = 1;
entries[2].entry = 2;
- err = pci_enable_msix(mdev->pdev, entries, ARRAY_SIZE(entries));
- if (err) {
- if (err > 0)
- mthca_info(mdev, "Only %d MSI-X vectors available, "
- "not using MSI-X\n", err);
+ err = pci_enable_msix_exact(mdev->pdev, entries, ARRAY_SIZE(entries));
+ if (err)
return err;
- }
mdev->eq_table.eq[MTHCA_EQ_COMP ].msi_x_vector = entries[0].vector;
mdev->eq_table.eq[MTHCA_EQ_ASYNC].msi_x_vector = entries[1].vector;
struct qib_msix_entry *qib_msix_entry)
{
int ret;
- u32 tabsize = 0;
- u16 msix_flags;
+ int nvec = *msixcnt;
struct msix_entry *msix_entry;
int i;
+ ret = pci_msix_vec_count(dd->pcidev);
+ if (ret < 0)
+ goto do_intx;
+
+ nvec = min(nvec, ret);
+
/* We can't pass qib_msix_entry array to qib_msix_setup
* so use a dummy msix_entry array and copy the allocated
* irq back to the qib_msix_entry array. */
- msix_entry = kmalloc(*msixcnt * sizeof(*msix_entry), GFP_KERNEL);
- if (!msix_entry) {
- ret = -ENOMEM;
+ msix_entry = kmalloc(nvec * sizeof(*msix_entry), GFP_KERNEL);
+ if (!msix_entry)
goto do_intx;
- }
- for (i = 0; i < *msixcnt; i++)
+
+ for (i = 0; i < nvec; i++)
msix_entry[i] = qib_msix_entry[i].msix;
- pci_read_config_word(dd->pcidev, pos + PCI_MSIX_FLAGS, &msix_flags);
- tabsize = 1 + (msix_flags & PCI_MSIX_FLAGS_QSIZE);
- if (tabsize > *msixcnt)
- tabsize = *msixcnt;
- ret = pci_enable_msix(dd->pcidev, msix_entry, tabsize);
- if (ret > 0) {
- tabsize = ret;
- ret = pci_enable_msix(dd->pcidev, msix_entry, tabsize);
- }
-do_intx:
- if (ret) {
- qib_dev_err(dd,
- "pci_enable_msix %d vectors failed: %d, falling back to INTx\n",
- tabsize, ret);
- tabsize = 0;
- }
- for (i = 0; i < tabsize; i++)
+ ret = pci_enable_msix_range(dd->pcidev, msix_entry, 1, nvec);
+ if (ret < 0)
+ goto free_msix_entry;
+ else
+ nvec = ret;
+
+ for (i = 0; i < nvec; i++)
qib_msix_entry[i].msix = msix_entry[i];
+
kfree(msix_entry);
- *msixcnt = tabsize;
+ *msixcnt = nvec;
+ return;
- if (ret)
- qib_enable_intx(dd->pcidev);
+free_msix_entry:
+ kfree(msix_entry);
+do_intx:
+ qib_dev_err(dd, "pci_enable_msix_range %d vectors failed: %d, "
+ "falling back to INTx\n", nvec, ret);
+ *msixcnt = 0;
+ qib_enable_intx(dd->pcidev);
}
/**
INIT_DELAYED_WORK(&onkey->work, da9055_onkey_work);
- irq = regmap_irq_get_virq(da9055->irq_data, irq);
err = request_threaded_irq(irq, NULL, da9055_onkey_irq,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
"ONKEY", onkey);
soc_button_remove(pdev);
return error;
}
+ continue;
}
priv->children[i] = pd;
case 6:
case 7:
case 8:
+ case 9:
etd->hw_version = 4;
break;
default:
}
#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
+/* This list has been kindly provided by Synaptics. */
+static const char * const topbuttonpad_pnp_ids[] = {
+ "LEN0017",
+ "LEN0018",
+ "LEN0019",
+ "LEN0023",
+ "LEN002A",
+ "LEN002B",
+ "LEN002C",
+ "LEN002D",
+ "LEN002E",
+ "LEN0033", /* Helix */
+ "LEN0034", /* T431s, T540, X1 Carbon 2nd */
+ "LEN0035", /* X240 */
+ "LEN0036", /* T440 */
+ "LEN0037",
+ "LEN0038",
+ "LEN0041",
+ "LEN0042", /* Yoga */
+ "LEN0045",
+ "LEN0046",
+ "LEN0047",
+ "LEN0048",
+ "LEN0049",
+ "LEN2000",
+ "LEN2001",
+ "LEN2002",
+ "LEN2003",
+ "LEN2004", /* L440 */
+ "LEN2005",
+ "LEN2006",
+ "LEN2007",
+ "LEN2008",
+ "LEN2009",
+ "LEN200A",
+ "LEN200B",
+ NULL
+};
/*****************************************************************************
* Synaptics communications functions
input_abs_set_res(dev, y_code, priv->y_res);
}
-static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
+static void set_input_params(struct psmouse *psmouse,
+ struct synaptics_data *priv)
{
+ struct input_dev *dev = psmouse->dev;
int i;
/* Things that apply to both modes */
if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
__set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
+ /* See if this buttonpad has a top button area */
+ if (!strncmp(psmouse->ps2dev.serio->firmware_id, "PNP:", 4)) {
+ for (i = 0; topbuttonpad_pnp_ids[i]; i++) {
+ if (strstr(psmouse->ps2dev.serio->firmware_id,
+ topbuttonpad_pnp_ids[i])) {
+ __set_bit(INPUT_PROP_TOPBUTTONPAD,
+ dev->propbit);
+ break;
+ }
+ }
+ }
/* Clickpads report only left button */
__clear_bit(BTN_RIGHT, dev->keybit);
__clear_bit(BTN_MIDDLE, dev->keybit);
},
.driver_data = (int []){1232, 5710, 1156, 4696},
},
+ {
+ /* Lenovo ThinkPad T431s */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T431"),
+ },
+ .driver_data = (int []){1024, 5112, 2024, 4832},
+ },
{
/* Lenovo ThinkPad T440s */
.matches = {
},
.driver_data = (int []){1024, 5112, 2024, 4832},
},
+ {
+ /* Lenovo ThinkPad L440 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L440"),
+ },
+ .driver_data = (int []){1024, 5112, 2024, 4832},
+ },
{
/* Lenovo ThinkPad T540p */
.matches = {
},
.driver_data = (int []){1024, 5056, 2058, 4832},
},
+ {
+ /* Lenovo ThinkPad L540 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L540"),
+ },
+ .driver_data = (int []){1024, 5112, 2024, 4832},
+ },
+ {
+ /* Lenovo Yoga S1 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION,
+ "ThinkPad S1 Yoga"),
+ },
+ .driver_data = (int []){1232, 5710, 1156, 4696},
+ },
+ {
+ /* Lenovo ThinkPad X1 Carbon Haswell (3rd generation) */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION,
+ "ThinkPad X1 Carbon 2nd"),
+ },
+ .driver_data = (int []){1024, 5112, 2024, 4832},
+ },
#endif
{ }
};
priv->capabilities, priv->ext_cap, priv->ext_cap_0c,
priv->board_id, priv->firmware_id);
- set_input_params(psmouse->dev, priv);
+ set_input_params(psmouse, priv);
/*
* Encode touchpad model so that it can be used to set
static char i8042_pnp_kbd_name[32];
static char i8042_pnp_aux_name[32];
+static void i8042_pnp_id_to_string(struct pnp_id *id, char *dst, int dst_size)
+{
+ strlcpy(dst, "PNP:", dst_size);
+
+ while (id) {
+ strlcat(dst, " ", dst_size);
+ strlcat(dst, id->id, dst_size);
+ id = id->next;
+ }
+}
+
static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
{
if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name));
strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
}
+ i8042_pnp_id_to_string(dev->id, i8042_kbd_firmware_id,
+ sizeof(i8042_kbd_firmware_id));
/* Keyboard ports are always supposed to be wakeup-enabled */
device_set_wakeup_enable(&dev->dev, true);
strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name));
strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name));
}
+ i8042_pnp_id_to_string(dev->id, i8042_aux_firmware_id,
+ sizeof(i8042_aux_firmware_id));
i8042_pnp_aux_devices++;
return 0;
#endif
static bool i8042_bypass_aux_irq_test;
+static char i8042_kbd_firmware_id[128];
+static char i8042_aux_firmware_id[128];
#include "i8042.h"
serio->dev.parent = &i8042_platform_device->dev;
strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name));
strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
+ strlcpy(serio->firmware_id, i8042_kbd_firmware_id,
+ sizeof(serio->firmware_id));
port->serio = serio;
port->irq = I8042_KBD_IRQ;
if (idx < 0) {
strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name));
strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+ strlcpy(serio->firmware_id, i8042_aux_firmware_id,
+ sizeof(serio->firmware_id));
serio->close = i8042_port_close;
} else {
snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx);
return retval;
}
+static ssize_t firmware_id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct serio *serio = to_serio_port(dev);
+
+ return sprintf(buf, "%s\n", serio->firmware_id);
+}
+
static DEVICE_ATTR_RO(type);
static DEVICE_ATTR_RO(proto);
static DEVICE_ATTR_RO(id);
static DEVICE_ATTR_WO(drvctl);
static DEVICE_ATTR(description, S_IRUGO, serio_show_description, NULL);
static DEVICE_ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode);
+static DEVICE_ATTR_RO(firmware_id);
static struct attribute *serio_device_attrs[] = {
&dev_attr_modalias.attr,
&dev_attr_description.attr,
&dev_attr_drvctl.attr,
&dev_attr_bind_mode.attr,
+ &dev_attr_firmware_id.attr,
NULL
};
SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto);
SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id);
SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
+
SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
+ if (serio->firmware_id[0])
+ SERIO_ADD_UEVENT_VAR("SERIO_FIRMWARE_ID=%s",
+ serio->firmware_id);
+
return 0;
}
#undef SERIO_ADD_UEVENT_VAR
#define HID_USAGE_PAGE_DIGITIZER 0x0d
#define HID_USAGE_PAGE_DESKTOP 0x01
#define HID_USAGE 0x09
-#define HID_USAGE_X 0x30
-#define HID_USAGE_Y 0x31
-#define HID_USAGE_X_TILT 0x3d
-#define HID_USAGE_Y_TILT 0x3e
-#define HID_USAGE_FINGER 0x22
-#define HID_USAGE_STYLUS 0x20
-#define HID_USAGE_CONTACTMAX 0x55
+#define HID_USAGE_X ((HID_USAGE_PAGE_DESKTOP << 16) | 0x30)
+#define HID_USAGE_Y ((HID_USAGE_PAGE_DESKTOP << 16) | 0x31)
+#define HID_USAGE_PRESSURE ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x30)
+#define HID_USAGE_X_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3d)
+#define HID_USAGE_Y_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3e)
+#define HID_USAGE_FINGER ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x22)
+#define HID_USAGE_STYLUS ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x20)
+#define HID_USAGE_CONTACTMAX ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x55)
#define HID_COLLECTION 0xa1
#define HID_COLLECTION_LOGICAL 0x02
#define HID_COLLECTION_END 0xc0
-enum {
- WCM_UNDEFINED = 0,
- WCM_DESKTOP,
- WCM_DIGITIZER,
-};
-
struct hid_descriptor {
struct usb_descriptor_header header;
__le16 bcdHID;
char limit = 0;
/* result has to be defined as int for some devices */
int result = 0, touch_max = 0;
- int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0;
+ int i = 0, page = 0, finger = 0, pen = 0;
unsigned char *report;
report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL);
switch (report[i]) {
case HID_USAGE_PAGE:
- switch (report[i + 1]) {
- case HID_USAGE_PAGE_DIGITIZER:
- usage = WCM_DIGITIZER;
- i++;
- break;
-
- case HID_USAGE_PAGE_DESKTOP:
- usage = WCM_DESKTOP;
- i++;
- break;
- }
+ page = report[i + 1];
+ i++;
break;
case HID_USAGE:
- switch (report[i + 1]) {
+ switch (page << 16 | report[i + 1]) {
case HID_USAGE_X:
- if (usage == WCM_DESKTOP) {
- if (finger) {
- features->device_type = BTN_TOOL_FINGER;
- /* touch device at least supports one touch point */
- touch_max = 1;
- switch (features->type) {
- case TABLETPC2FG:
- features->pktlen = WACOM_PKGLEN_TPC2FG;
- break;
-
- case MTSCREEN:
- case WACOM_24HDT:
- features->pktlen = WACOM_PKGLEN_MTOUCH;
- break;
-
- case MTTPC:
- features->pktlen = WACOM_PKGLEN_MTTPC;
- break;
-
- case BAMBOO_PT:
- features->pktlen = WACOM_PKGLEN_BBTOUCH;
- break;
-
- default:
- features->pktlen = WACOM_PKGLEN_GRAPHIRE;
- break;
- }
-
- switch (features->type) {
- case BAMBOO_PT:
- features->x_phy =
- get_unaligned_le16(&report[i + 5]);
- features->x_max =
- get_unaligned_le16(&report[i + 8]);
- i += 15;
- break;
-
- case WACOM_24HDT:
- features->x_max =
- get_unaligned_le16(&report[i + 3]);
- features->x_phy =
- get_unaligned_le16(&report[i + 8]);
- features->unit = report[i - 1];
- features->unitExpo = report[i - 3];
- i += 12;
- break;
-
- default:
- features->x_max =
- get_unaligned_le16(&report[i + 3]);
- features->x_phy =
- get_unaligned_le16(&report[i + 6]);
- features->unit = report[i + 9];
- features->unitExpo = report[i + 11];
- i += 12;
- break;
- }
- } else if (pen) {
- /* penabled only accepts exact bytes of data */
- if (features->type >= TABLETPC)
- features->pktlen = WACOM_PKGLEN_GRAPHIRE;
- features->device_type = BTN_TOOL_PEN;
+ if (finger) {
+ features->device_type = BTN_TOOL_FINGER;
+ /* touch device at least supports one touch point */
+ touch_max = 1;
+ switch (features->type) {
+ case TABLETPC2FG:
+ features->pktlen = WACOM_PKGLEN_TPC2FG;
+ break;
+
+ case MTSCREEN:
+ case WACOM_24HDT:
+ features->pktlen = WACOM_PKGLEN_MTOUCH;
+ break;
+
+ case MTTPC:
+ features->pktlen = WACOM_PKGLEN_MTTPC;
+ break;
+
+ case BAMBOO_PT:
+ features->pktlen = WACOM_PKGLEN_BBTOUCH;
+ break;
+
+ default:
+ features->pktlen = WACOM_PKGLEN_GRAPHIRE;
+ break;
+ }
+
+ switch (features->type) {
+ case BAMBOO_PT:
+ features->x_phy =
+ get_unaligned_le16(&report[i + 5]);
+ features->x_max =
+ get_unaligned_le16(&report[i + 8]);
+ i += 15;
+ break;
+
+ case WACOM_24HDT:
features->x_max =
get_unaligned_le16(&report[i + 3]);
- i += 4;
+ features->x_phy =
+ get_unaligned_le16(&report[i + 8]);
+ features->unit = report[i - 1];
+ features->unitExpo = report[i - 3];
+ i += 12;
+ break;
+
+ default:
+ features->x_max =
+ get_unaligned_le16(&report[i + 3]);
+ features->x_phy =
+ get_unaligned_le16(&report[i + 6]);
+ features->unit = report[i + 9];
+ features->unitExpo = report[i + 11];
+ i += 12;
+ break;
}
+ } else if (pen) {
+ /* penabled only accepts exact bytes of data */
+ if (features->type >= TABLETPC)
+ features->pktlen = WACOM_PKGLEN_GRAPHIRE;
+ features->device_type = BTN_TOOL_PEN;
+ features->x_max =
+ get_unaligned_le16(&report[i + 3]);
+ i += 4;
}
break;
case HID_USAGE_Y:
- if (usage == WCM_DESKTOP) {
- if (finger) {
- switch (features->type) {
- case TABLETPC2FG:
- case MTSCREEN:
- case MTTPC:
- features->y_max =
- get_unaligned_le16(&report[i + 3]);
- features->y_phy =
- get_unaligned_le16(&report[i + 6]);
- i += 7;
- break;
-
- case WACOM_24HDT:
- features->y_max =
- get_unaligned_le16(&report[i + 3]);
- features->y_phy =
- get_unaligned_le16(&report[i - 2]);
- i += 7;
- break;
-
- case BAMBOO_PT:
- features->y_phy =
- get_unaligned_le16(&report[i + 3]);
- features->y_max =
- get_unaligned_le16(&report[i + 6]);
- i += 12;
- break;
-
- default:
- features->y_max =
- features->x_max;
- features->y_phy =
- get_unaligned_le16(&report[i + 3]);
- i += 4;
- break;
- }
- } else if (pen) {
+ if (finger) {
+ switch (features->type) {
+ case TABLETPC2FG:
+ case MTSCREEN:
+ case MTTPC:
+ features->y_max =
+ get_unaligned_le16(&report[i + 3]);
+ features->y_phy =
+ get_unaligned_le16(&report[i + 6]);
+ i += 7;
+ break;
+
+ case WACOM_24HDT:
+ features->y_max =
+ get_unaligned_le16(&report[i + 3]);
+ features->y_phy =
+ get_unaligned_le16(&report[i - 2]);
+ i += 7;
+ break;
+
+ case BAMBOO_PT:
+ features->y_phy =
+ get_unaligned_le16(&report[i + 3]);
+ features->y_max =
+ get_unaligned_le16(&report[i + 6]);
+ i += 12;
+ break;
+
+ default:
features->y_max =
+ features->x_max;
+ features->y_phy =
get_unaligned_le16(&report[i + 3]);
i += 4;
+ break;
}
+ } else if (pen) {
+ features->y_max =
+ get_unaligned_le16(&report[i + 3]);
+ i += 4;
}
break;
wacom_retrieve_report_data(intf, features);
i++;
break;
+
+ case HID_USAGE_PRESSURE:
+ if (pen) {
+ features->pressure_max =
+ get_unaligned_le16(&report[i + 3]);
+ i += 4;
+ }
+ break;
}
break;
case HID_COLLECTION_END:
/* reset UsagePage and Finger */
- finger = usage = 0;
+ finger = page = 0;
break;
case HID_COLLECTION:
static int wacom_dtu_irq(struct wacom_wac *wacom)
{
- struct wacom_features *features = &wacom->features;
- char *data = wacom->data;
+ unsigned char *data = wacom->data;
struct input_dev *input = wacom->input;
- int prox = data[1] & 0x20, pressure;
+ int prox = data[1] & 0x20;
dev_dbg(input->dev.parent,
"%s: received report #%d", __func__, data[0]);
input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
- pressure = ((data[7] & 0x01) << 8) | data[6];
- if (pressure < 0)
- pressure = features->pressure_max + pressure + 1;
- input_report_abs(input, ABS_PRESSURE, pressure);
+ input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x01) << 8) | data[6]);
input_report_key(input, BTN_TOUCH, data[1] & 0x05);
if (!prox) /* out-prox */
wacom->id[0] = 0;
static int wacom_24hdt_irq(struct wacom_wac *wacom)
{
struct input_dev *input = wacom->input;
- char *data = wacom->data;
+ unsigned char *data = wacom->data;
int i;
int current_num_contacts = data[61];
int contacts_to_send = 0;
static int wacom_mt_touch(struct wacom_wac *wacom)
{
struct input_dev *input = wacom->input;
- char *data = wacom->data;
+ unsigned char *data = wacom->data;
int i;
int current_num_contacts = data[2];
int contacts_to_send = 0;
static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
{
- char *data = wacom->data;
+ unsigned char *data = wacom->data;
struct input_dev *input = wacom->input;
bool prox;
int x = 0, y = 0;
static int wacom_tpc_pen(struct wacom_wac *wacom)
{
- struct wacom_features *features = &wacom->features;
- char *data = wacom->data;
+ unsigned char *data = wacom->data;
struct input_dev *input = wacom->input;
- int pressure;
bool prox = data[1] & 0x20;
if (!wacom->shared->stylus_in_proximity) /* first in prox */
input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
- pressure = ((data[7] & 0x01) << 8) | data[6];
- if (pressure < 0)
- pressure = features->pressure_max + pressure + 1;
- input_report_abs(input, ABS_PRESSURE, pressure);
+ input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x03) << 8) | data[6]);
input_report_key(input, BTN_TOUCH, data[1] & 0x05);
input_report_key(input, wacom->tool[0], prox);
return 1;
static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
{
- char *data = wacom->data;
+ unsigned char *data = wacom->data;
dev_dbg(wacom->input->dev.parent,
"%s: received report #%d\n", __func__, data[0]);
case DTU:
if (features->type == DTUS) {
input_set_capability(input_dev, EV_MSC, MSC_SERIAL);
- for (i = 0; i < 3; i++)
+ for (i = 0; i < 4; i++)
__set_bit(BTN_0 + i, input_dev->keybit);
}
__set_bit(BTN_TOOL_PEN, input_dev->keybit);
name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct ads7846 *ts = dev_get_drvdata(dev); \
- ssize_t v = ads7846_read12_ser(dev, \
+ ssize_t v = ads7846_read12_ser(&ts->spi->dev, \
READ_12BIT_SER(var)); \
if (v < 0) \
return v; \
do {
next = pmd_addr_end(addr, end);
- ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, end, pfn,
+ ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, next, pfn,
prot, stage);
phys += next - addr;
} while (pmd++, addr = next, addr < end);
ret = arm_smmu_handle_mapping(smmu_domain, iova, 0, size, 0);
arm_smmu_tlb_inv_context(&smmu_domain->root_cfg);
- return ret ? ret : size;
+ return ret ? 0 : size;
}
static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
info->seg = pci_domain_nr(dev->bus);
info->level = level;
if (event == BUS_NOTIFY_ADD_DEVICE) {
- for (tmp = dev, level--; tmp; tmp = tmp->bus->self) {
+ for (tmp = dev; tmp; tmp = tmp->bus->self) {
+ level--;
info->path[level].device = PCI_SLOT(tmp->devfn);
info->path[level].function = PCI_FUNC(tmp->devfn);
if (pci_is_root_bus(tmp->bus))
if (level == 1)
return freelist;
- for (pte = page_address(pg); !first_pte_in_page(pte); pte++) {
+ pte = page_address(pg);
+ do {
if (dma_pte_present(pte) && !dma_pte_superpage(pte))
freelist = dma_pte_list_pagetables(domain, level - 1,
pte, freelist);
- }
+ pte++;
+ } while (!first_pte_in_page(pte));
return freelist;
}
bridge_devfn = dev_tmp->devfn;
}
spin_lock_irqsave(&device_domain_lock, flags);
- info = dmar_search_domain_by_dev_info(segment, bus, devfn);
+ info = dmar_search_domain_by_dev_info(segment,
+ bridge_bus,
+ bridge_devfn);
if (info) {
iommu = info->iommu;
domain = info->domain;
bool force)
{
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
- unsigned int shift = (gic_irq(d) % 4) * 8;
- unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+ unsigned int cpu, shift = (gic_irq(d) % 4) * 8;
u32 val, mask, bit;
+ if (!force)
+ cpu = cpumask_any_and(mask_val, cpu_online_mask);
+ else
+ cpu = cpumask_first(mask_val);
+
if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
return -EINVAL;
#include <linux/list.h>
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/of.h>
#include <linux/of_address.h>
static void vic_handle_irq_cascaded(unsigned int irq, struct irq_desc *desc)
{
u32 stat, hwirq;
+ struct irq_chip *host_chip = irq_desc_get_chip(desc);
struct vic_device *vic = irq_desc_get_handler_data(desc);
+ chained_irq_enter(host_chip, desc);
+
while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) {
hwirq = ffs(stat) - 1;
generic_handle_irq(irq_find_mapping(vic->domain, hwirq));
}
+
+ chained_irq_exit(host_chip, desc);
}
/*
* Viresh Kumar <viresh.linux@gmail.com>
*
* Copyright (C) 2012 ST Microelectronics
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
ulong a;
ulong flags;
int i;
- char cbuf[60];
+ char cbuf[80];
isdn_ctrl cmd;
icn_cdef cdef;
char __user *arg;
break;
if ((c->arg & 255) < ICN_BCH) {
char *p;
- char dial[50];
char dcode[4];
a = c->arg;
} else
/* Normal Dial */
strcpy(dcode, "CAL");
- strcpy(dial, p);
- sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
- dcode, dial, c->parm.setup.si1,
- c->parm.setup.si2, c->parm.setup.eazmsn);
+ snprintf(cbuf, sizeof(cbuf),
+ "%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);
}
break;
default:
pr_err("Invalid chameleon descriptor type 0x%x\n",
dtype);
+ kfree(header);
return -EINVAL;
}
num_cells++;
sh->group = NULL;
}
list_del_init(&sh->lru);
- atomic_inc(&sh->count);
- BUG_ON(atomic_read(&sh->count) != 1);
+ BUG_ON(atomic_inc_return(&sh->count) != 1);
return sh;
}
config VIDEO_TIMBERDALE
tristate "Support for timberdale Video In/LogiWIN"
- depends on VIDEO_V4L2 && I2C && DMADEVICES
+ depends on MFD_TIMBERDALE && VIDEO_V4L2 && I2C && DMADEVICES
select DMA_ENGINE
select TIMB_DMA
select VIDEO_ADV7180
depends on SGI_GRU
default n
---help---
- This option enables addition debugging code for the SGI GRU driver. If
- you are unsure, say N.
+ This option enables additional debugging code for the SGI GRU driver.
+ If you are unsure, say N.
config APDS9802ALS
tristate "Medfield Avago APDS9802 ALS Sensor module"
GENWQE_REQU_STATE_MAX,
};
+/**
+ * struct genwqe_sgl - Scatter gather list describing user-space memory
+ * @sgl: scatter gather list needs to be 128 byte aligned
+ * @sgl_dma_addr: dma address of sgl
+ * @sgl_size: size of area used for sgl
+ * @user_addr: user-space address of memory area
+ * @user_size: size of user-space memory area
+ * @page: buffer for partial pages if needed
+ * @page_dma_addr: dma address partial pages
+ */
+struct genwqe_sgl {
+ dma_addr_t sgl_dma_addr;
+ struct sg_entry *sgl;
+ size_t sgl_size; /* size of sgl */
+
+ void __user *user_addr; /* user-space base-address */
+ size_t user_size; /* size of memory area */
+
+ unsigned long nr_pages;
+ unsigned long fpage_offs;
+ size_t fpage_size;
+ size_t lpage_size;
+
+ void *fpage;
+ dma_addr_t fpage_dma_addr;
+
+ void *lpage;
+ dma_addr_t lpage_dma_addr;
+};
+
+int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+ void __user *user_addr, size_t user_size);
+
+int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+ dma_addr_t *dma_list);
+
+int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl);
+
/**
* struct ddcb_requ - Kernel internal representation of the DDCB request
* @cmd: User space representation of the DDCB execution request
struct ddcb_queue *queue; /* associated queue */
struct dma_mapping dma_mappings[DDCB_FIXUPS];
- struct sg_entry *sgl[DDCB_FIXUPS];
- dma_addr_t sgl_dma_addr[DDCB_FIXUPS];
- size_t sgl_size[DDCB_FIXUPS];
+ struct genwqe_sgl sgls[DDCB_FIXUPS];
/* kernel/user shared content */
struct genwqe_ddcb_cmd cmd; /* ddcb_no for this request */
int genwqe_user_vunmap(struct genwqe_dev *cd, struct dma_mapping *m,
struct ddcb_requ *req);
-struct sg_entry *genwqe_alloc_sgl(struct genwqe_dev *cd, int num_pages,
- dma_addr_t *dma_addr, size_t *sgl_size);
-
-void genwqe_free_sgl(struct genwqe_dev *cd, struct sg_entry *sg_list,
- dma_addr_t dma_addr, size_t size);
-
-int genwqe_setup_sgl(struct genwqe_dev *cd,
- unsigned long offs,
- unsigned long size,
- struct sg_entry *sgl, /* genwqe sgl */
- dma_addr_t dma_addr, size_t sgl_size,
- dma_addr_t *dma_list, int page_offs, int num_pages);
-
-int genwqe_check_sgl(struct genwqe_dev *cd, struct sg_entry *sg_list,
- int size);
-
static inline bool dma_mapping_used(struct dma_mapping *m)
{
if (!m)
break;
new = (old | DDCB_NEXT_BE32);
+
+ wmb();
icrc_hsi_shi = cmpxchg(&prev_ddcb->icrc_hsi_shi_32, old, new);
if (icrc_hsi_shi == old)
/* Queue must be re-started by updating QUEUE_OFFSET */
ddcb_mark_tapped(pddcb);
num = (u64)ddcb_no << 8;
+
+ wmb();
__genwqe_writeq(cd, queue->IO_QUEUE_OFFSET, num); /* start queue */
return RET_DDCB_TAPPED;
*/
int genwqe_finish_queue(struct genwqe_dev *cd)
{
- int i, rc, in_flight;
+ int i, rc = 0, in_flight;
int waitmax = genwqe_ddcb_software_timeout;
struct pci_dev *pci_dev = cd->pci_dev;
struct ddcb_queue *queue = &cd->queue;
case '1':
cmdopts = 0x1C;
break; /* download/erase_first/part_1 */
- case 'v': /* cmdopts = 0x0c (VPD) */
+ case 'v':
+ cmdopts = 0x0C;
+ break; /* download/erase_first/vpd */
default:
return -EINVAL;
}
cmdopts = 0x1A;
break; /* upload/part_1 */
case 'v':
+ cmdopts = 0x0A;
+ break; /* upload/vpd */
default:
return -EINVAL;
}
__genwqe_del_mapping(cfile, dma_map);
genwqe_user_vunmap(cd, dma_map, req);
}
- if (req->sgl[i] != NULL) {
- genwqe_free_sgl(cd, req->sgl[i],
- req->sgl_dma_addr[i],
- req->sgl_size[i]);
- req->sgl[i] = NULL;
- req->sgl_dma_addr[i] = 0x0;
- req->sgl_size[i] = 0;
- }
-
+ if (req->sgls[i].sgl != NULL)
+ genwqe_free_sync_sgl(cd, &req->sgls[i]);
}
return 0;
}
case ATS_TYPE_SGL_RDWR:
case ATS_TYPE_SGL_RD: {
- int page_offs, nr_pages, offs;
+ int page_offs;
u_addr = be64_to_cpu(*((__be64 *)
&cmd->asiv[asiv_offs]));
page_offs = 0;
}
- offs = offset_in_page(u_addr);
- nr_pages = DIV_ROUND_UP(offs + u_size, PAGE_SIZE);
-
/* create genwqe style scatter gather list */
- req->sgl[i] = genwqe_alloc_sgl(cd, m->nr_pages,
- &req->sgl_dma_addr[i],
- &req->sgl_size[i]);
- if (req->sgl[i] == NULL) {
- rc = -ENOMEM;
+ rc = genwqe_alloc_sync_sgl(cd, &req->sgls[i],
+ (void __user *)u_addr,
+ u_size);
+ if (rc != 0)
goto err_out;
- }
- genwqe_setup_sgl(cd, offs, u_size,
- req->sgl[i],
- req->sgl_dma_addr[i],
- req->sgl_size[i],
- m->dma_list,
- page_offs,
- nr_pages);
+
+ genwqe_setup_sgl(cd, &req->sgls[i],
+ &m->dma_list[page_offs]);
*((__be64 *)&cmd->asiv[asiv_offs]) =
- cpu_to_be64(req->sgl_dma_addr[i]);
+ cpu_to_be64(req->sgls[i].sgl_dma_addr);
break;
}
return roundup(len, PAGE_SIZE);
}
-struct sg_entry *genwqe_alloc_sgl(struct genwqe_dev *cd, int num_pages,
- dma_addr_t *dma_addr, size_t *sgl_size)
+/**
+ * genwqe_alloc_sync_sgl() - Allocate memory for sgl and overlapping pages
+ *
+ * Allocates memory for sgl and overlapping pages. Pages which might
+ * overlap other user-space memory blocks are being cached for DMAs,
+ * such that we do not run into syncronization issues. Data is copied
+ * from user-space into the cached pages.
+ */
+int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+ void __user *user_addr, size_t user_size)
{
+ int rc;
struct pci_dev *pci_dev = cd->pci_dev;
- struct sg_entry *sgl;
- *sgl_size = genwqe_sgl_size(num_pages);
- if (get_order(*sgl_size) > MAX_ORDER) {
+ sgl->fpage_offs = offset_in_page((unsigned long)user_addr);
+ sgl->fpage_size = min_t(size_t, PAGE_SIZE-sgl->fpage_offs, user_size);
+ sgl->nr_pages = DIV_ROUND_UP(sgl->fpage_offs + user_size, PAGE_SIZE);
+ sgl->lpage_size = (user_size - sgl->fpage_size) % PAGE_SIZE;
+
+ dev_dbg(&pci_dev->dev, "[%s] uaddr=%p usize=%8ld nr_pages=%ld "
+ "fpage_offs=%lx fpage_size=%ld lpage_size=%ld\n",
+ __func__, user_addr, user_size, sgl->nr_pages,
+ sgl->fpage_offs, sgl->fpage_size, sgl->lpage_size);
+
+ sgl->user_addr = user_addr;
+ sgl->user_size = user_size;
+ sgl->sgl_size = genwqe_sgl_size(sgl->nr_pages);
+
+ if (get_order(sgl->sgl_size) > MAX_ORDER) {
dev_err(&pci_dev->dev,
"[%s] err: too much memory requested!\n", __func__);
- return NULL;
+ return -ENOMEM;
}
- sgl = __genwqe_alloc_consistent(cd, *sgl_size, dma_addr);
- if (sgl == NULL) {
+ sgl->sgl = __genwqe_alloc_consistent(cd, sgl->sgl_size,
+ &sgl->sgl_dma_addr);
+ if (sgl->sgl == NULL) {
dev_err(&pci_dev->dev,
"[%s] err: no memory available!\n", __func__);
- return NULL;
+ return -ENOMEM;
}
- return sgl;
+ /* Only use buffering on incomplete pages */
+ if ((sgl->fpage_size != 0) && (sgl->fpage_size != PAGE_SIZE)) {
+ sgl->fpage = __genwqe_alloc_consistent(cd, PAGE_SIZE,
+ &sgl->fpage_dma_addr);
+ if (sgl->fpage == NULL)
+ goto err_out;
+
+ /* Sync with user memory */
+ if (copy_from_user(sgl->fpage + sgl->fpage_offs,
+ user_addr, sgl->fpage_size)) {
+ rc = -EFAULT;
+ goto err_out;
+ }
+ }
+ if (sgl->lpage_size != 0) {
+ sgl->lpage = __genwqe_alloc_consistent(cd, PAGE_SIZE,
+ &sgl->lpage_dma_addr);
+ if (sgl->lpage == NULL)
+ goto err_out1;
+
+ /* Sync with user memory */
+ if (copy_from_user(sgl->lpage, user_addr + user_size -
+ sgl->lpage_size, sgl->lpage_size)) {
+ rc = -EFAULT;
+ goto err_out1;
+ }
+ }
+ return 0;
+
+ err_out1:
+ __genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage,
+ sgl->fpage_dma_addr);
+ err_out:
+ __genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl,
+ sgl->sgl_dma_addr);
+ return -ENOMEM;
}
-int genwqe_setup_sgl(struct genwqe_dev *cd,
- unsigned long offs,
- unsigned long size,
- struct sg_entry *sgl,
- dma_addr_t dma_addr, size_t sgl_size,
- dma_addr_t *dma_list, int page_offs, int num_pages)
+int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+ dma_addr_t *dma_list)
{
int i = 0, j = 0, p;
unsigned long dma_offs, map_offs;
- struct pci_dev *pci_dev = cd->pci_dev;
dma_addr_t prev_daddr = 0;
struct sg_entry *s, *last_s = NULL;
-
- /* sanity checks */
- if (offs > PAGE_SIZE) {
- dev_err(&pci_dev->dev,
- "[%s] too large start offs %08lx\n", __func__, offs);
- return -EFAULT;
- }
- if (sgl_size < genwqe_sgl_size(num_pages)) {
- dev_err(&pci_dev->dev,
- "[%s] sgl_size too small %08lx for %d pages\n",
- __func__, sgl_size, num_pages);
- return -EFAULT;
- }
+ size_t size = sgl->user_size;
dma_offs = 128; /* next block if needed/dma_offset */
- map_offs = offs; /* offset in first page */
+ map_offs = sgl->fpage_offs; /* offset in first page */
- s = &sgl[0]; /* first set of 8 entries */
+ s = &sgl->sgl[0]; /* first set of 8 entries */
p = 0; /* page */
- while (p < num_pages) {
+ while (p < sgl->nr_pages) {
dma_addr_t daddr;
unsigned int size_to_map;
/* always write the chaining entry, cleanup is done later */
j = 0;
- s[j].target_addr = cpu_to_be64(dma_addr + dma_offs);
+ s[j].target_addr = cpu_to_be64(sgl->sgl_dma_addr + dma_offs);
s[j].len = cpu_to_be32(128);
s[j].flags = cpu_to_be32(SG_CHAINED);
j++;
while (j < 8) {
/* DMA mapping for requested page, offs, size */
size_to_map = min(size, PAGE_SIZE - map_offs);
- daddr = dma_list[page_offs + p] + map_offs;
+
+ if ((p == 0) && (sgl->fpage != NULL)) {
+ daddr = sgl->fpage_dma_addr + map_offs;
+
+ } else if ((p == sgl->nr_pages - 1) &&
+ (sgl->lpage != NULL)) {
+ daddr = sgl->lpage_dma_addr;
+ } else {
+ daddr = dma_list[p] + map_offs;
+ }
+
size -= size_to_map;
map_offs = 0;
size_to_map);
p++; /* process next page */
- if (p == num_pages)
+ if (p == sgl->nr_pages)
goto fixup; /* nothing to do */
prev_daddr = daddr + size_to_map;
j++;
p++; /* process next page */
- if (p == num_pages)
+ if (p == sgl->nr_pages)
goto fixup; /* nothing to do */
}
dma_offs += 128;
return 0;
}
-void genwqe_free_sgl(struct genwqe_dev *cd, struct sg_entry *sg_list,
- dma_addr_t dma_addr, size_t size)
+/**
+ * genwqe_free_sync_sgl() - Free memory for sgl and overlapping pages
+ *
+ * After the DMA transfer has been completed we free the memory for
+ * the sgl and the cached pages. Data is being transfered from cached
+ * pages into user-space buffers.
+ */
+int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl)
{
- __genwqe_free_consistent(cd, size, sg_list, dma_addr);
+ int rc;
+ struct pci_dev *pci_dev = cd->pci_dev;
+
+ if (sgl->fpage) {
+ if (copy_to_user(sgl->user_addr, sgl->fpage + sgl->fpage_offs,
+ sgl->fpage_size)) {
+ dev_err(&pci_dev->dev, "[%s] err: copying fpage!\n",
+ __func__);
+ rc = -EFAULT;
+ }
+ __genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage,
+ sgl->fpage_dma_addr);
+ sgl->fpage = NULL;
+ sgl->fpage_dma_addr = 0;
+ }
+ if (sgl->lpage) {
+ if (copy_to_user(sgl->user_addr + sgl->user_size -
+ sgl->lpage_size, sgl->lpage,
+ sgl->lpage_size)) {
+ dev_err(&pci_dev->dev, "[%s] err: copying lpage!\n",
+ __func__);
+ rc = -EFAULT;
+ }
+ __genwqe_free_consistent(cd, PAGE_SIZE, sgl->lpage,
+ sgl->lpage_dma_addr);
+ sgl->lpage = NULL;
+ sgl->lpage_dma_addr = 0;
+ }
+ __genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl,
+ sgl->sgl_dma_addr);
+
+ sgl->sgl = NULL;
+ sgl->sgl_dma_addr = 0x0;
+ sgl->sgl_size = 0;
+ return rc;
}
/**
#include <asm/byteorder.h>
#include <linux/genwqe/genwqe_card.h>
-#define DRV_VERS_STRING "2.0.0"
+#define DRV_VERS_STRING "2.0.15"
/*
* Static minor number assignement, until we decide/implement
#define MEI_DEV_ID_LPT_HR 0x8CBA /* Lynx Point H Refresh */
#define MEI_DEV_ID_WPT_LP 0x9CBA /* Wildcat Point LP */
+
+/* Host Firmware Status Registers in PCI Config Space */
+#define PCI_CFG_HFS_1 0x40
+#define PCI_CFG_HFS_2 0x48
+
/*
* MEI HW Section
*/
cl->status = 0;
list_del(&cb->list);
- if (MEI_WRITING == cl->writing_state &&
- cb->fop_type == MEI_FOP_WRITE &&
+ if (cb->fop_type == MEI_FOP_WRITE &&
cl != &dev->iamthif_cl) {
cl_dbg(dev, cl, "MEI WRITE COMPLETE\n");
cl->writing_state = MEI_WRITE_COMPLETE;
goto out;
}
- if (MEI_WRITE_COMPLETE == cl->writing_state)
- mask |= (POLLIN | POLLRDNORM);
+ mask |= (POLLIN | POLLRDNORM);
out:
mutex_unlock(&dev->device_lock);
const struct pci_device_id *ent)
{
u32 reg;
- if (ent->device == MEI_DEV_ID_PBG_1) {
- pci_read_config_dword(pdev, 0x48, ®);
- /* make sure that bit 9 is up and bit 10 is down */
- if ((reg & 0x600) == 0x200) {
- dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
- return false;
- }
+ /* Cougar Point || Patsburg */
+ if (ent->device == MEI_DEV_ID_CPT_1 ||
+ ent->device == MEI_DEV_ID_PBG_1) {
+ pci_read_config_dword(pdev, PCI_CFG_HFS_2, ®);
+ /* make sure that bit 9 (NM) is up and bit 10 (DM) is down */
+ if ((reg & 0x600) == 0x200)
+ goto no_mei;
}
+
+ /* Lynx Point */
+ if (ent->device == MEI_DEV_ID_LPT_H ||
+ ent->device == MEI_DEV_ID_LPT_W ||
+ ent->device == MEI_DEV_ID_LPT_HR) {
+ /* Read ME FW Status check for SPS Firmware */
+ pci_read_config_dword(pdev, PCI_CFG_HFS_1, ®);
+ /* if bits [19:16] = 15, running SPS Firmware */
+ if ((reg & 0xf0000) == 0xf0000)
+ goto no_mei;
+ }
+
return true;
+
+no_mei:
+ dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
+ return false;
}
/**
* mei_probe - Device Initialization Routine
*
* Copyright © 2010 STMicroelectronics.
* Ashish Priyadarshi
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
module_platform_driver(spear_smi_driver);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.linux.kernel@gmail.com>");
MODULE_DESCRIPTION("MTD SMI driver for serial nor flash chips");
pci_disable_device(pdev);
}
+#ifdef CONFIG_PM_SLEEP
static int
bnx2_suspend(struct device *device)
{
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static SIMPLE_DEV_PM_OPS(bnx2_pm_ops, bnx2_suspend, bnx2_resume);
#define BNX2_PM_OPS (&bnx2_pm_ops)
if (tg3_flag(tp, MAX_RXPEND_64) &&
tp->rx_pending > 63)
tp->rx_pending = 63;
- tp->rx_jumbo_pending = ering->rx_jumbo_pending;
+
+ if (tg3_flag(tp, JUMBO_RING_ENABLE))
+ tp->rx_jumbo_pending = ering->rx_jumbo_pending;
for (i = 0; i < tp->irq_max; i++)
tp->napi[i].tx_pending = ering->tx_pending;
config NET_CADENCE
bool "Cadence devices"
- depends on HAS_IOMEM
+ depends on HAS_IOMEM && (ARM || AVR32 || COMPILE_TEST)
default y
---help---
If you have a network (Ethernet) card belonging to this class, say Y.
config ARM_AT91_ETHER
tristate "AT91RM9200 Ethernet support"
- depends on HAS_DMA
+ depends on HAS_DMA && (ARCH_AT91RM9200 || COMPILE_TEST)
select MACB
---help---
If you wish to compile a kernel for the AT91RM9200 and enable
config MACB
tristate "Cadence MACB/GEM support"
- depends on HAS_DMA
+ depends on HAS_DMA && (PLATFORM_AT32AP || ARCH_AT91 || ARCH_PICOXCELL || ARCH_ZYNQ || COMPILE_TEST)
select PHYLIB
---help---
The Cadence MACB ethernet interface is found on many Atmel AT32 and
req->params = htons(L2T_W_PORT(e->lport) | L2T_W_NOREPLY(!sync));
req->l2t_idx = htons(e->idx);
req->vlan = htons(e->vlan);
- if (e->neigh)
+ if (e->neigh && !(e->neigh->dev->flags & IFF_LOOPBACK))
memcpy(e->dmac, e->neigh->ha, sizeof(e->dmac));
memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac));
if (e) {
spin_lock(&e->lock); /* avoid race with t4_l2t_free */
e->state = L2T_STATE_RESOLVING;
+ if (neigh->dev->flags & IFF_LOOPBACK)
+ memcpy(e->dmac, physdev->dev_addr, sizeof(e->dmac));
memcpy(e->addr, addr, addr_len);
e->ifindex = ifidx;
e->hash = hash;
SF_RD_ID = 0x9f, /* read ID */
SF_ERASE_SECTOR = 0xd8, /* erase sector */
- FW_MAX_SIZE = 512 * 1024,
+ FW_MAX_SIZE = 16 * SF_SEC_SIZE,
};
/**
#define BE_FLAGS_NAPI_ENABLED (1 << 9)
#define BE_FLAGS_QNQ_ASYNC_EVT_RCVD (1 << 11)
#define BE_FLAGS_VXLAN_OFFLOADS (1 << 12)
+#define BE_FLAGS_SETUP_DONE (1 << 13)
#define BE_UC_PMAC_COUNT 30
#define BE_VF_UC_PMAC_COUNT 2
bool dummy_wrb;
int i, pending_txqs;
- /* Wait for a max of 200ms for all the tx-completions to arrive. */
+ /* Stop polling for compls when HW has been silent for 10ms */
do {
pending_txqs = adapter->num_tx_qs;
for_all_tx_queues(adapter, txo, i) {
+ cmpl = 0;
+ num_wrbs = 0;
txq = &txo->q;
while ((txcp = be_tx_compl_get(&txo->cq))) {
end_idx =
if (cmpl) {
be_cq_notify(adapter, txo->cq.id, false, cmpl);
atomic_sub(num_wrbs, &txq->used);
- cmpl = 0;
- num_wrbs = 0;
+ timeo = 0;
}
if (atomic_read(&txq->used) == 0)
pending_txqs--;
}
- if (pending_txqs == 0 || ++timeo > 200)
+ if (pending_txqs == 0 || ++timeo > 10 || be_hw_error(adapter))
break;
mdelay(1);
struct be_eq_obj *eqo;
int i;
+ /* This protection is needed as be_close() may be called even when the
+ * adapter is in cleared state (after eeh perm failure)
+ */
+ if (!(adapter->flags & BE_FLAGS_SETUP_DONE))
+ return 0;
+
be_roce_dev_close(adapter);
if (adapter->flags & BE_FLAGS_NAPI_ENABLED) {
be_clear_queues(adapter);
be_msix_disable(adapter);
+ adapter->flags &= ~BE_FLAGS_SETUP_DONE;
return 0;
}
adapter->phy.fc_autoneg = 1;
be_schedule_worker(adapter);
+ adapter->flags |= BE_FLAGS_SETUP_DONE;
return 0;
err:
be_clear(adapter);
#define MVNETA_RX_MIN_FRAME_SIZE 0x247c
#define MVNETA_SERDES_CFG 0x24A0
#define MVNETA_SGMII_SERDES_PROTO 0x0cc7
-#define MVNETA_RGMII_SERDES_PROTO 0x0667
+#define MVNETA_QSGMII_SERDES_PROTO 0x0667
#define MVNETA_TYPE_PRIO 0x24bc
#define MVNETA_FORCE_UNI BIT(21)
#define MVNETA_TXQ_CMD_1 0x24e4
}
/* Power up the port */
-static void mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
+static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
{
- u32 val;
+ u32 ctrl;
/* MAC Cause register should be cleared */
mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0);
- if (phy_mode == PHY_INTERFACE_MODE_SGMII)
- mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
- else
- mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_RGMII_SERDES_PROTO);
+ ctrl = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
- val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
-
- val |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII;
+ /* Even though it might look weird, when we're configured in
+ * SGMII or QSGMII mode, the RGMII bit needs to be set.
+ */
+ switch(phy_mode) {
+ case PHY_INTERFACE_MODE_QSGMII:
+ mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO);
+ ctrl |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII;
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
+ ctrl |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII;
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ ctrl |= MVNETA_GMAC2_PORT_RGMII;
+ break;
+ default:
+ return -EINVAL;
+ }
/* Cancel Port Reset */
- val &= ~MVNETA_GMAC2_PORT_RESET;
- mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
+ ctrl &= ~MVNETA_GMAC2_PORT_RESET;
+ mvreg_write(pp, MVNETA_GMAC_CTRL_2, ctrl);
while ((mvreg_read(pp, MVNETA_GMAC_CTRL_2) &
MVNETA_GMAC2_PORT_RESET) != 0)
continue;
+
+ return 0;
}
/* Device initialization routine */
dev_err(&pdev->dev, "can't init eth hal\n");
goto err_free_stats;
}
- mvneta_port_power_up(pp, phy_mode);
+
+ err = mvneta_port_power_up(pp, phy_mode);
+ if (err < 0) {
+ dev_err(&pdev->dev, "can't power up port\n");
+ goto err_deinit;
+ }
dram_target_info = mv_mbus_dram_info();
if (dram_target_info)
cq->ring = ring;
cq->is_tx = mode;
- spin_lock_init(&cq->lock);
/* Allocate HW buffers on provided NUMA node.
* dev->numa_node is used in mtt range allocation flow.
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_cq *cq;
- unsigned long flags;
int i;
for (i = 0; i < priv->rx_ring_num; i++) {
cq = priv->rx_cq[i];
- spin_lock_irqsave(&cq->lock, flags);
- napi_synchronize(&cq->napi);
- mlx4_en_process_rx_cq(dev, cq, 0);
- spin_unlock_irqrestore(&cq->lock, flags);
+ napi_schedule(&cq->napi);
}
}
#endif
/* Allow large DMA segments, up to the firmware limit of 1 GB */
dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- err = -ENOMEM;
- goto err_release_regions;
- }
-
- dev = &priv->dev;
+ dev = pci_get_drvdata(pdev);
+ priv = mlx4_priv(dev);
dev->pdev = pdev;
INIT_LIST_HEAD(&priv->ctx_list);
spin_lock_init(&priv->ctx_lock);
} else {
atomic_inc(&pf_loading);
err = pci_enable_sriov(pdev, total_vfs);
- atomic_dec(&pf_loading);
if (err) {
mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n",
err);
+ atomic_dec(&pf_loading);
err = 0;
} else {
mlx4_warn(dev, "Running in master mode\n");
mlx4_sense_init(dev);
mlx4_start_sense(dev);
- priv->pci_dev_data = pci_dev_data;
- pci_set_drvdata(pdev, dev);
+ priv->removed = 0;
+
+ if (mlx4_is_master(dev) && dev->num_vfs)
+ atomic_dec(&pf_loading);
return 0;
if (!mlx4_is_slave(dev))
mlx4_free_ownership(dev);
+ if (mlx4_is_master(dev) && dev->num_vfs)
+ atomic_dec(&pf_loading);
+
kfree(priv->dev.dev_vfs);
err_free_dev:
static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
+ struct mlx4_priv *priv;
+ struct mlx4_dev *dev;
+
printk_once(KERN_INFO "%s", mlx4_version);
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ dev = &priv->dev;
+ pci_set_drvdata(pdev, dev);
+ priv->pci_dev_data = id->driver_data;
+
return __mlx4_init_one(pdev, id->driver_data);
}
-static void mlx4_remove_one(struct pci_dev *pdev)
+static void __mlx4_remove_one(struct pci_dev *pdev)
{
struct mlx4_dev *dev = pci_get_drvdata(pdev);
struct mlx4_priv *priv = mlx4_priv(dev);
+ int pci_dev_data;
int p;
- if (dev) {
- /* in SRIOV it is not allowed to unload the pf's
- * driver while there are alive vf's */
- if (mlx4_is_master(dev)) {
- if (mlx4_how_many_lives_vf(dev))
- printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n");
- }
- mlx4_stop_sense(dev);
- mlx4_unregister_device(dev);
+ if (priv->removed)
+ return;
- for (p = 1; p <= dev->caps.num_ports; p++) {
- mlx4_cleanup_port_info(&priv->port[p]);
- mlx4_CLOSE_PORT(dev, p);
- }
+ pci_dev_data = priv->pci_dev_data;
- if (mlx4_is_master(dev))
- mlx4_free_resource_tracker(dev,
- RES_TR_FREE_SLAVES_ONLY);
-
- mlx4_cleanup_counters_table(dev);
- mlx4_cleanup_qp_table(dev);
- mlx4_cleanup_srq_table(dev);
- mlx4_cleanup_cq_table(dev);
- mlx4_cmd_use_polling(dev);
- mlx4_cleanup_eq_table(dev);
- mlx4_cleanup_mcg_table(dev);
- mlx4_cleanup_mr_table(dev);
- mlx4_cleanup_xrcd_table(dev);
- mlx4_cleanup_pd_table(dev);
+ /* in SRIOV it is not allowed to unload the pf's
+ * driver while there are alive vf's */
+ if (mlx4_is_master(dev) && mlx4_how_many_lives_vf(dev))
+ printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n");
+ mlx4_stop_sense(dev);
+ mlx4_unregister_device(dev);
- if (mlx4_is_master(dev))
- mlx4_free_resource_tracker(dev,
- RES_TR_FREE_STRUCTS_ONLY);
-
- iounmap(priv->kar);
- mlx4_uar_free(dev, &priv->driver_uar);
- mlx4_cleanup_uar_table(dev);
- if (!mlx4_is_slave(dev))
- mlx4_clear_steering(dev);
- mlx4_free_eq_table(dev);
- if (mlx4_is_master(dev))
- mlx4_multi_func_cleanup(dev);
- mlx4_close_hca(dev);
- if (mlx4_is_slave(dev))
- mlx4_multi_func_cleanup(dev);
- mlx4_cmd_cleanup(dev);
-
- if (dev->flags & MLX4_FLAG_MSI_X)
- pci_disable_msix(pdev);
- if (dev->flags & MLX4_FLAG_SRIOV) {
- mlx4_warn(dev, "Disabling SR-IOV\n");
- pci_disable_sriov(pdev);
- }
+ for (p = 1; p <= dev->caps.num_ports; p++) {
+ mlx4_cleanup_port_info(&priv->port[p]);
+ mlx4_CLOSE_PORT(dev, p);
+ }
- if (!mlx4_is_slave(dev))
- mlx4_free_ownership(dev);
+ if (mlx4_is_master(dev))
+ mlx4_free_resource_tracker(dev,
+ RES_TR_FREE_SLAVES_ONLY);
- kfree(dev->caps.qp0_tunnel);
- kfree(dev->caps.qp0_proxy);
- kfree(dev->caps.qp1_tunnel);
- kfree(dev->caps.qp1_proxy);
- kfree(dev->dev_vfs);
+ mlx4_cleanup_counters_table(dev);
+ mlx4_cleanup_qp_table(dev);
+ mlx4_cleanup_srq_table(dev);
+ mlx4_cleanup_cq_table(dev);
+ mlx4_cmd_use_polling(dev);
+ mlx4_cleanup_eq_table(dev);
+ mlx4_cleanup_mcg_table(dev);
+ mlx4_cleanup_mr_table(dev);
+ mlx4_cleanup_xrcd_table(dev);
+ mlx4_cleanup_pd_table(dev);
- kfree(priv);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
+ if (mlx4_is_master(dev))
+ mlx4_free_resource_tracker(dev,
+ RES_TR_FREE_STRUCTS_ONLY);
+
+ iounmap(priv->kar);
+ mlx4_uar_free(dev, &priv->driver_uar);
+ mlx4_cleanup_uar_table(dev);
+ if (!mlx4_is_slave(dev))
+ mlx4_clear_steering(dev);
+ mlx4_free_eq_table(dev);
+ if (mlx4_is_master(dev))
+ mlx4_multi_func_cleanup(dev);
+ mlx4_close_hca(dev);
+ if (mlx4_is_slave(dev))
+ mlx4_multi_func_cleanup(dev);
+ mlx4_cmd_cleanup(dev);
+
+ if (dev->flags & MLX4_FLAG_MSI_X)
+ pci_disable_msix(pdev);
+ if (dev->flags & MLX4_FLAG_SRIOV) {
+ mlx4_warn(dev, "Disabling SR-IOV\n");
+ pci_disable_sriov(pdev);
+ dev->num_vfs = 0;
}
+
+ if (!mlx4_is_slave(dev))
+ mlx4_free_ownership(dev);
+
+ kfree(dev->caps.qp0_tunnel);
+ kfree(dev->caps.qp0_proxy);
+ kfree(dev->caps.qp1_tunnel);
+ kfree(dev->caps.qp1_proxy);
+ kfree(dev->dev_vfs);
+
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ memset(priv, 0, sizeof(*priv));
+ priv->pci_dev_data = pci_dev_data;
+ priv->removed = 1;
+}
+
+static void mlx4_remove_one(struct pci_dev *pdev)
+{
+ struct mlx4_dev *dev = pci_get_drvdata(pdev);
+ struct mlx4_priv *priv = mlx4_priv(dev);
+
+ __mlx4_remove_one(pdev);
+ kfree(priv);
+ pci_set_drvdata(pdev, NULL);
}
int mlx4_restart_one(struct pci_dev *pdev)
int pci_dev_data;
pci_dev_data = priv->pci_dev_data;
- mlx4_remove_one(pdev);
+ __mlx4_remove_one(pdev);
return __mlx4_init_one(pdev, pci_dev_data);
}
static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
- mlx4_remove_one(pdev);
+ __mlx4_remove_one(pdev);
return state == pci_channel_io_perm_failure ?
PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev)
{
- const struct pci_device_id *id;
- int ret;
+ struct mlx4_dev *dev = pci_get_drvdata(pdev);
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ int ret;
- id = pci_match_id(mlx4_pci_table, pdev);
- ret = __mlx4_init_one(pdev, id->driver_data);
+ ret = __mlx4_init_one(pdev, priv->pci_dev_data);
return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
}
spinlock_t ctx_lock;
int pci_dev_data;
+ int removed;
struct list_head pgdir_list;
struct mutex pgdir_mutex;
struct mlx4_cq mcq;
struct mlx4_hwq_resources wqres;
int ring;
- spinlock_t lock;
struct net_device *dev;
struct napi_struct napi;
int size;
ahw->max_mac_filters = nic_info.max_mac_filters;
ahw->max_mtu = nic_info.max_mtu;
- adapter->max_tx_rings = ahw->max_tx_ques;
- adapter->max_sds_rings = ahw->max_rx_ques;
/* eSwitch capability indicates vNIC mode.
* vNIC and SRIOV are mutually exclusive operational modes.
* If SR-IOV capability is detected, SR-IOV physical function
int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter)
{
struct qlcnic_hardware_context *ahw = adapter->ahw;
+ u16 max_sds_rings, max_tx_rings;
int ret;
ret = qlcnic_83xx_get_nic_configuration(adapter);
if (qlcnic_83xx_config_vnic_opmode(adapter))
return -EIO;
- adapter->max_sds_rings = QLCNIC_MAX_VNIC_SDS_RINGS;
- adapter->max_tx_rings = QLCNIC_MAX_VNIC_TX_RINGS;
+ max_sds_rings = QLCNIC_MAX_VNIC_SDS_RINGS;
+ max_tx_rings = QLCNIC_MAX_VNIC_TX_RINGS;
} else if (ret == QLC_83XX_DEFAULT_OPMODE) {
ahw->nic_mode = QLCNIC_DEFAULT_MODE;
adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver;
ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
- adapter->max_sds_rings = QLCNIC_MAX_SDS_RINGS;
- adapter->max_tx_rings = QLCNIC_MAX_TX_RINGS;
+ max_sds_rings = QLCNIC_MAX_SDS_RINGS;
+ max_tx_rings = QLCNIC_MAX_TX_RINGS;
} else {
return -EIO;
}
+ adapter->max_sds_rings = min(ahw->max_rx_ques, max_sds_rings);
+ adapter->max_tx_rings = min(ahw->max_tx_ques, max_tx_rings);
+
return 0;
}
goto disable_intr;
}
+ INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work);
+
err = qlcnic_83xx_setup_mbx_intr(adapter);
if (err)
goto disable_mbx_intr;
qlcnic_83xx_clear_function_resources(adapter);
-
- INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work);
-
+ qlcnic_dcb_enable(adapter->dcb);
qlcnic_83xx_initialize_nic(adapter, 1);
+ qlcnic_dcb_get_info(adapter->dcb);
/* Configure default, SR-IOV or Virtual NIC mode of operation */
err = qlcnic_83xx_configure_opmode(adapter);
npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques);
npar_info->capabilities = le32_to_cpu(nic_info->capabilities);
npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu);
- adapter->max_tx_rings = npar_info->max_tx_ques;
- adapter->max_sds_rings = npar_info->max_rx_ques;
}
qlcnic_free_mbx_args(&cmd);
arg2 &= ~BIT_3;
break;
case QLCNIC_ADD_VLAN:
+ arg1 &= ~(0x0ffff << 16);
arg1 |= (BIT_2 | BIT_5);
arg1 |= (esw_cfg->vlan_id << 16);
break;
goto out_free_cfg;
}
- qlcnic_dcb_get_info(dcb);
-
return 0;
out_free_cfg:
kfree(dcb->cfg);
else
num_msix += adapter->drv_tx_rings;
- if (adapter->drv_rss_rings > 0)
+ if (adapter->drv_rss_rings > 0)
num_msix += adapter->drv_rss_rings;
else
num_msix += adapter->drv_sds_rings;
return -ENOMEM;
}
-restore:
for (vector = 0; vector < num_msix; vector++)
adapter->msix_entries[vector].entry = vector;
+restore:
err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
- if (err == 0) {
- adapter->ahw->num_msix = num_msix;
- if (adapter->drv_tss_rings > 0)
- adapter->drv_tx_rings = adapter->drv_tss_rings;
+ if (err > 0) {
+ if (!adapter->drv_tss_rings && !adapter->drv_rss_rings)
+ return -ENOSPC;
- if (adapter->drv_rss_rings > 0)
- adapter->drv_sds_rings = adapter->drv_rss_rings;
- } else {
netdev_info(adapter->netdev,
"Unable to allocate %d MSI-X vectors, Available vectors %d\n",
num_msix, err);
"Restoring %d Tx, %d SDS rings for total %d vectors.\n",
adapter->drv_tx_rings, adapter->drv_sds_rings,
num_msix);
- goto restore;
- err = -EIO;
+ goto restore;
+ } else if (err < 0) {
+ return err;
}
- return err;
+ adapter->ahw->num_msix = num_msix;
+ if (adapter->drv_tss_rings > 0)
+ adapter->drv_tx_rings = adapter->drv_tss_rings;
+
+ if (adapter->drv_rss_rings > 0)
+ adapter->drv_sds_rings = adapter->drv_rss_rings;
+
+ return 0;
}
int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
goto err_out_free_hw;
}
- qlcnic_dcb_enable(adapter->dcb);
-
if (qlcnic_read_mac_addr(adapter))
dev_warn(&pdev->dev, "failed to read mac addr\n");
"Device does not support MSI interrupts\n");
if (qlcnic_82xx_check(adapter)) {
+ qlcnic_dcb_enable(adapter->dcb);
+ qlcnic_dcb_get_info(adapter->dcb);
err = qlcnic_setup_intr(adapter);
+
if (err) {
dev_err(&pdev->dev, "Failed to setup interrupt\n");
goto err_out_disable_msi;
{
struct net_device *netdev = adapter->netdev;
+ if (pci_vfs_assigned(adapter->pdev)) {
+ netdev_err(adapter->netdev,
+ "SR-IOV VFs belonging to port %d are assigned to VMs. SR-IOV can not be disabled on this port\n",
+ adapter->portnum);
+ netdev_info(adapter->netdev,
+ "Please detach SR-IOV VFs belonging to port %d from VMs, and then try to disable SR-IOV on this port\n",
+ adapter->portnum);
+ return -EPERM;
+ }
+
rtnl_lock();
if (netif_running(netdev))
__qlcnic_down(adapter, netdev);
{
int i;
- for (i = 0; i < adapter->ahw->max_vnic_func; i++) {
+ for (i = 0; i < adapter->ahw->total_nic_func; i++) {
if (adapter->npars[i].pci_func == pci_func)
return i;
}
struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_npar_func_cfg *np_cfg;
struct qlcnic_info nic_info;
+ u8 pci_func;
int i, ret;
u32 count;
count = size / sizeof(struct qlcnic_npar_func_cfg);
for (i = 0; i < adapter->ahw->total_nic_func; i++) {
- if (qlcnic_is_valid_nic_func(adapter, i) < 0)
- continue;
if (adapter->npars[i].pci_func >= count) {
dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n",
__func__, adapter->ahw->total_nic_func, count);
continue;
}
- ret = qlcnic_get_nic_info(adapter, &nic_info, i);
- if (ret)
- return ret;
if (!adapter->npars[i].eswitch_status)
continue;
- np_cfg[i].pci_func = i;
- np_cfg[i].op_mode = (u8)nic_info.op_mode;
- np_cfg[i].port_num = nic_info.phys_port;
- np_cfg[i].fw_capab = nic_info.capabilities;
- np_cfg[i].min_bw = nic_info.min_tx_bw;
- np_cfg[i].max_bw = nic_info.max_tx_bw;
- np_cfg[i].max_tx_queues = nic_info.max_tx_ques;
- np_cfg[i].max_rx_queues = nic_info.max_rx_ques;
+ pci_func = adapter->npars[i].pci_func;
+ if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
+ continue;
+ ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func);
+ if (ret)
+ return ret;
+
+ np_cfg[pci_func].pci_func = pci_func;
+ np_cfg[pci_func].op_mode = (u8)nic_info.op_mode;
+ np_cfg[pci_func].port_num = nic_info.phys_port;
+ np_cfg[pci_func].fw_capab = nic_info.capabilities;
+ np_cfg[pci_func].min_bw = nic_info.min_tx_bw;
+ np_cfg[pci_func].max_bw = nic_info.max_tx_bw;
+ np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques;
+ np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques;
}
return size;
}
/* If it was a port reset, trigger reallocation of MC resources.
* Note that on an MC reset nothing needs to be done now because we'll
* detect the MC reset later and handle it then.
+ * For an FLR, we never get an MC reset event, but the MC has reset all
+ * resources assigned to us, so we have to trigger reallocation now.
*/
- if (reset_type == RESET_TYPE_ALL && !rc)
+ if ((reset_type == RESET_TYPE_ALL ||
+ reset_type == RESET_TYPE_MCDI_TIMEOUT) && !rc)
efx_ef10_reset_mc_allocations(efx);
return rc;
}
return 0;
}
+static void efx_ef10_prepare_flr(struct efx_nic *efx)
+{
+ atomic_set(&efx->active_queues, 0);
+}
+
static bool efx_ef10_filter_equal(const struct efx_filter_spec *left,
const struct efx_filter_spec *right)
{
.probe_port = efx_mcdi_port_probe,
.remove_port = efx_mcdi_port_remove,
.fini_dmaq = efx_ef10_fini_dmaq,
+ .prepare_flr = efx_ef10_prepare_flr,
+ .finish_flr = efx_port_dummy_op_void,
.describe_stats = efx_ef10_describe_stats,
.update_stats = efx_ef10_update_stats,
.start_stats = efx_mcdi_mac_start_stats,
[RESET_TYPE_RECOVER_OR_ALL] = "RECOVER_OR_ALL",
[RESET_TYPE_WORLD] = "WORLD",
[RESET_TYPE_RECOVER_OR_DISABLE] = "RECOVER_OR_DISABLE",
+ [RESET_TYPE_MC_BIST] = "MC_BIST",
[RESET_TYPE_DISABLE] = "DISABLE",
[RESET_TYPE_TX_WATCHDOG] = "TX_WATCHDOG",
[RESET_TYPE_INT_ERROR] = "INT_ERROR",
[RESET_TYPE_DMA_ERROR] = "DMA_ERROR",
[RESET_TYPE_TX_SKIP] = "TX_SKIP",
[RESET_TYPE_MC_FAILURE] = "MC_FAILURE",
- [RESET_TYPE_MC_BIST] = "MC_BIST",
+ [RESET_TYPE_MCDI_TIMEOUT] = "MCDI_TIMEOUT (FLR)",
};
/* Reset workqueue. If any NIC has a hardware failure then a reset will be
/* Check that it is appropriate to restart the interface. All
* of these flags are safe to read under just the rtnl lock */
- if (efx->port_enabled || !netif_running(efx->net_dev))
+ if (efx->port_enabled || !netif_running(efx->net_dev) ||
+ efx->reset_pending)
return;
efx_start_port(efx);
{
EFX_ASSERT_RESET_SERIALISED(efx);
+ if (method == RESET_TYPE_MCDI_TIMEOUT)
+ efx->type->prepare_flr(efx);
+
efx_stop_all(efx);
efx_disable_interrupts(efx);
EFX_ASSERT_RESET_SERIALISED(efx);
+ if (method == RESET_TYPE_MCDI_TIMEOUT)
+ efx->type->finish_flr(efx);
+
+ /* Ensure that SRAM is initialised even if we're disabling the device */
rc = efx->type->init(efx);
if (rc) {
netif_err(efx, drv, efx->net_dev, "failed to initialise NIC\n");
/* Clear flags for the scopes we covered. We assume the NIC and
* driver are now quiescent so that there is no race here.
*/
- efx->reset_pending &= -(1 << (method + 1));
+ if (method < RESET_TYPE_MAX_METHOD)
+ efx->reset_pending &= -(1 << (method + 1));
+ else /* it doesn't fit into the well-ordered scope hierarchy */
+ __clear_bit(method, &efx->reset_pending);
/* Reinitialise bus-mastering, which may have been turned off before
* the reset was scheduled. This is still appropriate, even in the
case RESET_TYPE_DISABLE:
case RESET_TYPE_RECOVER_OR_DISABLE:
case RESET_TYPE_MC_BIST:
+ case RESET_TYPE_MCDI_TIMEOUT:
method = type;
netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset\n",
RESET_TYPE(method));
* @RESET_TYPE_WORLD: Reset as much as possible
* @RESET_TYPE_RECOVER_OR_DISABLE: Try to recover. Apply RESET_TYPE_DISABLE if
* unsuccessful.
+ * @RESET_TYPE_MC_BIST: MC entering BIST mode.
* @RESET_TYPE_DISABLE: Reset datapath, MAC and PHY; leave NIC disabled
* @RESET_TYPE_TX_WATCHDOG: reset due to TX watchdog
* @RESET_TYPE_INT_ERROR: reset due to internal error
* @RESET_TYPE_DMA_ERROR: DMA error
* @RESET_TYPE_TX_SKIP: hardware completed empty tx descriptors
* @RESET_TYPE_MC_FAILURE: MC reboot/assertion
+ * @RESET_TYPE_MCDI_TIMEOUT: MCDI timeout.
*/
enum reset_type {
- RESET_TYPE_INVISIBLE = 0,
- RESET_TYPE_RECOVER_OR_ALL = 1,
- RESET_TYPE_ALL = 2,
- RESET_TYPE_WORLD = 3,
- RESET_TYPE_RECOVER_OR_DISABLE = 4,
- RESET_TYPE_DISABLE = 5,
+ RESET_TYPE_INVISIBLE,
+ RESET_TYPE_RECOVER_OR_ALL,
+ RESET_TYPE_ALL,
+ RESET_TYPE_WORLD,
+ RESET_TYPE_RECOVER_OR_DISABLE,
+ RESET_TYPE_MC_BIST,
+ RESET_TYPE_DISABLE,
RESET_TYPE_MAX_METHOD,
RESET_TYPE_TX_WATCHDOG,
RESET_TYPE_INT_ERROR,
RESET_TYPE_DMA_ERROR,
RESET_TYPE_TX_SKIP,
RESET_TYPE_MC_FAILURE,
- RESET_TYPE_MC_BIST,
+ /* RESET_TYPE_MCDI_TIMEOUT is actually a method, not just a reason, but
+ * it doesn't fit the scope hierarchy (not well-ordered by inclusion).
+ * We encode this by having its enum value be greater than
+ * RESET_TYPE_MAX_METHOD. This also prevents issuing it with
+ * efx_ioctl_reset.
+ */
+ RESET_TYPE_MCDI_TIMEOUT,
RESET_TYPE_MAX,
};
.fini_dmaq = efx_farch_fini_dmaq,
.prepare_flush = falcon_prepare_flush,
.finish_flush = efx_port_dummy_op_void,
+ .prepare_flr = efx_port_dummy_op_void,
+ .finish_flr = efx_farch_finish_flr,
.describe_stats = falcon_describe_nic_stats,
.update_stats = falcon_update_nic_stats,
.start_stats = falcon_start_nic_stats,
.fini_dmaq = efx_farch_fini_dmaq,
.prepare_flush = falcon_prepare_flush,
.finish_flush = efx_port_dummy_op_void,
+ .prepare_flr = efx_port_dummy_op_void,
+ .finish_flr = efx_farch_finish_flr,
.describe_stats = falcon_describe_nic_stats,
.update_stats = falcon_update_nic_stats,
.start_stats = falcon_start_nic_stats,
return rc;
}
+/* Reset queue and flush accounting after FLR
+ *
+ * One possible cause of FLR recovery is that DMA may be failing (eg. if bus
+ * mastering was disabled), in which case we don't receive (RXQ) flush
+ * completion events. This means that efx->rxq_flush_outstanding remained at 4
+ * after the FLR; also, efx->active_queues was non-zero (as no flush completion
+ * events were received, and we didn't go through efx_check_tx_flush_complete())
+ * If we don't fix this up, on the next call to efx_realloc_channels() we won't
+ * flush any RX queues because efx->rxq_flush_outstanding is at the limit of 4
+ * for batched flush requests; and the efx->active_queues gets messed up because
+ * we keep incrementing for the newly initialised queues, but it never went to
+ * zero previously. Then we get a timeout every time we try to restart the
+ * queues, as it doesn't go back to zero when we should be flushing the queues.
+ */
+void efx_farch_finish_flr(struct efx_nic *efx)
+{
+ atomic_set(&efx->rxq_flush_pending, 0);
+ atomic_set(&efx->rxq_flush_outstanding, 0);
+ atomic_set(&efx->active_queues, 0);
+}
+
+
/**************************************************************************
*
* Event queue processing
static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
bool *was_attached_out);
static bool efx_mcdi_poll_once(struct efx_nic *efx);
-
-static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx)
-{
- EFX_BUG_ON_PARANOID(!efx->mcdi);
- return &efx->mcdi->iface;
-}
+static void efx_mcdi_abandon(struct efx_nic *efx);
int efx_mcdi_init(struct efx_nic *efx)
{
rc = 0;
}
+ efx_mcdi_abandon(efx);
+
/* Close the race with efx_mcdi_ev_cpl() executing just too late
* and completing a request we've just cancelled, by ensuring
* that the seqno check therein fails.
if (efx->mc_bist_for_other_fn)
return -ENETDOWN;
+ if (mcdi->mode == MCDI_MODE_FAIL)
+ return -ENETDOWN;
+
efx_mcdi_acquire_sync(mcdi);
efx_mcdi_send_request(efx, cmd, inbuf, inlen);
return 0;
return;
mcdi = efx_mcdi(efx);
- if (mcdi->mode == MCDI_MODE_POLL)
+ /* If already in polling mode, nothing to do.
+ * If in fail-fast state, don't switch to polled completion.
+ * FLR recovery will do that later.
+ */
+ if (mcdi->mode == MCDI_MODE_POLL || mcdi->mode == MCDI_MODE_FAIL)
return;
/* We can switch from event completion to polled completion, because
mcdi = efx_mcdi(efx);
- /* We must be in polling mode so no more requests can be queued */
- BUG_ON(mcdi->mode != MCDI_MODE_POLL);
+ /* We must be in poll or fail mode so no more requests can be queued */
+ BUG_ON(mcdi->mode == MCDI_MODE_EVENTS);
del_timer_sync(&mcdi->async_timer);
return;
mcdi = efx_mcdi(efx);
-
- if (mcdi->mode == MCDI_MODE_EVENTS)
+ /* If already in event completion mode, nothing to do.
+ * If in fail-fast state, don't switch to event completion. FLR
+ * recovery will do that later.
+ */
+ if (mcdi->mode == MCDI_MODE_EVENTS || mcdi->mode == MCDI_MODE_FAIL)
return;
/* We can't switch from polled to event completion in the middle of a
spin_unlock(&mcdi->iface_lock);
}
+/* MCDI timeouts seen, so make all MCDI calls fail-fast and issue an FLR to try
+ * to recover.
+ */
+static void efx_mcdi_abandon(struct efx_nic *efx)
+{
+ struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+
+ if (xchg(&mcdi->mode, MCDI_MODE_FAIL) == MCDI_MODE_FAIL)
+ return; /* it had already been done */
+ netif_dbg(efx, hw, efx->net_dev, "MCDI is timing out; trying to recover\n");
+ efx_schedule_reset(efx, RESET_TYPE_MCDI_TIMEOUT);
+}
+
/* Called from falcon_process_eventq for MCDI events */
void efx_mcdi_process_event(struct efx_channel *channel,
efx_qword_t *event)
{
int rc;
+ /* If MCDI is down, we can't handle_assertion */
+ if (method == RESET_TYPE_MCDI_TIMEOUT) {
+ rc = pci_reset_function(efx->pci_dev);
+ if (rc)
+ return rc;
+ /* Re-enable polled MCDI completion */
+ if (efx->mcdi) {
+ struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
+ mcdi->mode = MCDI_MODE_POLL;
+ }
+ return 0;
+ }
+
/* Recover from a failed assertion pre-reset */
rc = efx_mcdi_handle_assertion(efx);
if (rc)
MCDI_STATE_COMPLETED,
};
+/**
+ * enum efx_mcdi_mode - MCDI transaction mode
+ * @MCDI_MODE_POLL: poll for MCDI completion, until timeout
+ * @MCDI_MODE_EVENTS: wait for an mcdi_event. On timeout, poll once
+ * @MCDI_MODE_FAIL: we think MCDI is dead, so fail-fast all calls
+ */
enum efx_mcdi_mode {
MCDI_MODE_POLL,
MCDI_MODE_EVENTS,
+ MCDI_MODE_FAIL,
};
/**
u32 fn_flags;
};
+static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx)
+{
+ EFX_BUG_ON_PARANOID(!efx->mcdi);
+ return &efx->mcdi->iface;
+}
+
#ifdef CONFIG_SFC_MCDI_MON
static inline struct efx_mcdi_mon *efx_mcdi_mon(struct efx_nic *efx)
{
* (for Falcon architecture)
* @finish_flush: Clean up after flushing the DMA queues (for Falcon
* architecture)
+ * @prepare_flr: Prepare for an FLR
+ * @finish_flr: Clean up after an FLR
* @describe_stats: Describe statistics for ethtool
* @update_stats: Update statistics not provided by event handling.
* Either argument may be %NULL.
int (*fini_dmaq)(struct efx_nic *efx);
void (*prepare_flush)(struct efx_nic *efx);
void (*finish_flush)(struct efx_nic *efx);
+ void (*prepare_flr)(struct efx_nic *efx);
+ void (*finish_flr)(struct efx_nic *efx);
size_t (*describe_stats)(struct efx_nic *efx, u8 *names);
size_t (*update_stats)(struct efx_nic *efx, u64 *full_stats,
struct rtnl_link_stats64 *core_stats);
int efx_nic_flush_queues(struct efx_nic *efx);
void siena_prepare_flush(struct efx_nic *efx);
int efx_farch_fini_dmaq(struct efx_nic *efx);
+void efx_farch_finish_flr(struct efx_nic *efx);
void siena_finish_flush(struct efx_nic *efx);
void falcon_start_nic_stats(struct efx_nic *efx);
void falcon_stop_nic_stats(struct efx_nic *efx);
.fini_dmaq = efx_farch_fini_dmaq,
.prepare_flush = siena_prepare_flush,
.finish_flush = siena_finish_flush,
+ .prepare_flr = efx_port_dummy_op_void,
+ .finish_flr = efx_farch_finish_flr,
.describe_stats = siena_describe_nic_stats,
.update_stats = siena_update_nic_stats,
.start_stats = efx_mcdi_mac_start_stats,
dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
if (status == 0)
- *data = buf[1];
+ *data = (buf[1] & mask) >> shift;
return status;
}
return -EINVAL;
}
- rc = at86rf230_read_subreg(lp, SR_AVDD_OK, &status);
- if (rc)
- return rc;
- if (!status) {
- dev_err(&lp->spi->dev, "AVDD error\n");
- return -EINVAL;
- }
-
return 0;
}
struct mdio_gpio_info {
struct mdiobb_ctrl ctrl;
- int mdc, mdio;
+ int mdc, mdio, mdo;
+ int mdc_active_low, mdio_active_low, mdo_active_low;
};
static void *mdio_gpio_of_get_data(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct mdio_gpio_platform_data *pdata;
+ enum of_gpio_flags flags;
int ret;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return NULL;
- ret = of_get_gpio(np, 0);
+ ret = of_get_gpio_flags(np, 0, &flags);
if (ret < 0)
return NULL;
pdata->mdc = ret;
+ pdata->mdc_active_low = flags & OF_GPIO_ACTIVE_LOW;
- ret = of_get_gpio(np, 1);
+ ret = of_get_gpio_flags(np, 1, &flags);
if (ret < 0)
return NULL;
pdata->mdio = ret;
+ pdata->mdio_active_low = flags & OF_GPIO_ACTIVE_LOW;
+
+ ret = of_get_gpio_flags(np, 2, &flags);
+ if (ret > 0) {
+ pdata->mdo = ret;
+ pdata->mdo_active_low = flags & OF_GPIO_ACTIVE_LOW;
+ }
return pdata;
}
struct mdio_gpio_info *bitbang =
container_of(ctrl, struct mdio_gpio_info, ctrl);
+ if (bitbang->mdo) {
+ /* Separate output pin. Always set its value to high
+ * when changing direction. If direction is input,
+ * assume the pin serves as pull-up. If direction is
+ * output, the default value is high.
+ */
+ gpio_set_value(bitbang->mdo, 1 ^ bitbang->mdo_active_low);
+ return;
+ }
+
if (dir)
- gpio_direction_output(bitbang->mdio, 1);
+ gpio_direction_output(bitbang->mdio,
+ 1 ^ bitbang->mdio_active_low);
else
gpio_direction_input(bitbang->mdio);
}
struct mdio_gpio_info *bitbang =
container_of(ctrl, struct mdio_gpio_info, ctrl);
- return gpio_get_value(bitbang->mdio);
+ return gpio_get_value(bitbang->mdio) ^ bitbang->mdio_active_low;
}
static void mdio_set(struct mdiobb_ctrl *ctrl, int what)
struct mdio_gpio_info *bitbang =
container_of(ctrl, struct mdio_gpio_info, ctrl);
- gpio_set_value(bitbang->mdio, what);
+ if (bitbang->mdo)
+ gpio_set_value(bitbang->mdo, what ^ bitbang->mdo_active_low);
+ else
+ gpio_set_value(bitbang->mdio, what ^ bitbang->mdio_active_low);
}
static void mdc_set(struct mdiobb_ctrl *ctrl, int what)
struct mdio_gpio_info *bitbang =
container_of(ctrl, struct mdio_gpio_info, ctrl);
- gpio_set_value(bitbang->mdc, what);
+ gpio_set_value(bitbang->mdc, what ^ bitbang->mdc_active_low);
}
static struct mdiobb_ops mdio_gpio_ops = {
struct mdio_gpio_info *bitbang;
int i;
- bitbang = kzalloc(sizeof(*bitbang), GFP_KERNEL);
+ bitbang = devm_kzalloc(dev, sizeof(*bitbang), GFP_KERNEL);
if (!bitbang)
goto out;
bitbang->ctrl.ops = &mdio_gpio_ops;
bitbang->ctrl.reset = pdata->reset;
bitbang->mdc = pdata->mdc;
+ bitbang->mdc_active_low = pdata->mdc_active_low;
bitbang->mdio = pdata->mdio;
+ bitbang->mdio_active_low = pdata->mdio_active_low;
+ bitbang->mdo = pdata->mdo;
+ bitbang->mdo_active_low = pdata->mdo_active_low;
new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
if (!new_bus)
- goto out_free_bitbang;
+ goto out;
new_bus->name = "GPIO Bitbanged MDIO",
snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id);
- if (gpio_request(bitbang->mdc, "mdc"))
+ if (devm_gpio_request(dev, bitbang->mdc, "mdc"))
+ goto out_free_bus;
+
+ if (devm_gpio_request(dev, bitbang->mdio, "mdio"))
goto out_free_bus;
- if (gpio_request(bitbang->mdio, "mdio"))
- goto out_free_mdc;
+ if (bitbang->mdo) {
+ if (devm_gpio_request(dev, bitbang->mdo, "mdo"))
+ goto out_free_bus;
+ gpio_direction_output(bitbang->mdo, 1);
+ gpio_direction_input(bitbang->mdio);
+ }
gpio_direction_output(bitbang->mdc, 0);
return new_bus;
-out_free_mdc:
- gpio_free(bitbang->mdc);
out_free_bus:
free_mdio_bitbang(new_bus);
-out_free_bitbang:
- kfree(bitbang);
out:
return NULL;
}
static void mdio_gpio_bus_deinit(struct device *dev)
{
struct mii_bus *bus = dev_get_drvdata(dev);
- struct mdio_gpio_info *bitbang = bus->priv;
- dev_set_drvdata(dev, NULL);
- gpio_free(bitbang->mdio);
- gpio_free(bitbang->mdc);
free_mdio_bitbang(bus);
- kfree(bitbang);
}
static void mdio_gpio_bus_destroy(struct device *dev)
if (err)
return err;
- return iptunnel_xmit(rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df,
- false);
+ return iptunnel_xmit(vs->sock->sk, rt, skb, src, dst, IPPROTO_UDP,
+ tos, ttl, df, false);
}
EXPORT_SYMBOL_GPL(vxlan_xmit_skb);
cosa_putstatus(cosa, 0);
cosa_getdata8(cosa);
cosa_putstatus(cosa, SR_RST);
-#ifdef MODULE
msleep(500);
-#else
- udelay(5*100000);
-#endif
/* Disable all IRQs from the card */
cosa_putstatus(cosa, 0);
"REQ",
"SOFT",
"HARD",
+ "RESET",
+ "RESET_REMAP",
};
static const char *cw1200_debug_mode(int mode)
#include "iwl-agn-hw.h"
/* Highest firmware API version supported */
-#define IWL7260_UCODE_API_MAX 8
-#define IWL3160_UCODE_API_MAX 8
+#define IWL7260_UCODE_API_MAX 9
+#define IWL3160_UCODE_API_MAX 9
/* Oldest version we won't warn about */
#define IWL7260_UCODE_API_OK 8
MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
+MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
cpu_to_le32(0xcc00aaaa),
cpu_to_le32(0x0000aaaa),
cpu_to_le32(0xc0004000),
- cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00004000),
cpu_to_le32(0xf0005000),
cpu_to_le32(0xf0005000),
},
/* Tx Tx disabled */
cpu_to_le32(0xaaaaaaaa),
cpu_to_le32(0xaaaaaaaa),
- cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xeeaaaaaa),
cpu_to_le32(0xaaaaaaaa),
cpu_to_le32(0xcc00ff28),
cpu_to_le32(0x0000aaaa),
cpu_to_le32(0xcc00aaaa),
cpu_to_le32(0x0000aaaa),
- cpu_to_le32(0xC0004000),
- cpu_to_le32(0xC0004000),
- cpu_to_le32(0xF0005000),
- cpu_to_le32(0xF0005000),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0xf0005000),
+ cpu_to_le32(0xf0005000),
},
};
struct iwl_rx_packet *pkt = rxb_addr(rxb);
u32 ant_isolation = le32_to_cpup((void *)pkt->data);
u8 __maybe_unused lower_bound, upper_bound;
+ int ret;
u8 lut;
struct iwl_bt_coex_cmd *bt_cmd;
memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[lut].lut20,
sizeof(bt_cmd->bt4_corun_lut40));
- return 0;
+ ret = iwl_mvm_send_cmd(mvm, &cmd);
+
+ kfree(bt_cmd);
+ return ret;
}
*/
iwl_mvm_remove_time_event(mvm, mvmvif,
&mvmvif->time_event_data);
+ iwl_mvm_sf_update(mvm, vif, false);
WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, CMD_SYNC));
} else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS |
BSS_CHANGED_QOS)) {
/* max allowed rate miss before sync LQ cmd */
#define IWL_MISSED_RATE_MAX 15
#define RS_STAY_IN_COLUMN_TIMEOUT (5*HZ)
-
+#define RS_IDLE_TIMEOUT (5*HZ)
static u8 rs_ht_to_legacy[] = {
[IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX,
RS_MIMO2,
};
-#define MAX_NEXT_COLUMNS 5
+#define MAX_NEXT_COLUMNS 7
#define MAX_COLUMN_CHECKS 3
typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm,
RS_COLUMN_LEGACY_ANT_B,
RS_COLUMN_SISO_ANT_A,
RS_COLUMN_SISO_ANT_B,
- RS_COLUMN_MIMO2,
- RS_COLUMN_MIMO2_SGI,
+ RS_COLUMN_INVALID,
+ RS_COLUMN_INVALID,
+ RS_COLUMN_INVALID,
+ RS_COLUMN_INVALID,
},
},
[RS_COLUMN_LEGACY_ANT_B] = {
RS_COLUMN_LEGACY_ANT_A,
RS_COLUMN_SISO_ANT_A,
RS_COLUMN_SISO_ANT_B,
- RS_COLUMN_MIMO2,
- RS_COLUMN_MIMO2_SGI,
+ RS_COLUMN_INVALID,
+ RS_COLUMN_INVALID,
+ RS_COLUMN_INVALID,
+ RS_COLUMN_INVALID,
},
},
[RS_COLUMN_SISO_ANT_A] = {
RS_COLUMN_MIMO2,
RS_COLUMN_SISO_ANT_A_SGI,
RS_COLUMN_SISO_ANT_B_SGI,
- RS_COLUMN_MIMO2_SGI,
+ RS_COLUMN_LEGACY_ANT_A,
+ RS_COLUMN_LEGACY_ANT_B,
+ RS_COLUMN_INVALID,
},
.checks = {
rs_siso_allow,
RS_COLUMN_MIMO2,
RS_COLUMN_SISO_ANT_B_SGI,
RS_COLUMN_SISO_ANT_A_SGI,
- RS_COLUMN_MIMO2_SGI,
+ RS_COLUMN_LEGACY_ANT_A,
+ RS_COLUMN_LEGACY_ANT_B,
+ RS_COLUMN_INVALID,
},
.checks = {
rs_siso_allow,
RS_COLUMN_SISO_ANT_A,
RS_COLUMN_SISO_ANT_B,
RS_COLUMN_MIMO2,
+ RS_COLUMN_LEGACY_ANT_A,
+ RS_COLUMN_LEGACY_ANT_B,
},
.checks = {
rs_siso_allow,
RS_COLUMN_SISO_ANT_B,
RS_COLUMN_SISO_ANT_A,
RS_COLUMN_MIMO2,
+ RS_COLUMN_LEGACY_ANT_A,
+ RS_COLUMN_LEGACY_ANT_B,
},
.checks = {
rs_siso_allow,
RS_COLUMN_SISO_ANT_A_SGI,
RS_COLUMN_SISO_ANT_B_SGI,
RS_COLUMN_MIMO2_SGI,
+ RS_COLUMN_LEGACY_ANT_A,
+ RS_COLUMN_LEGACY_ANT_B,
},
.checks = {
rs_mimo_allow,
RS_COLUMN_SISO_ANT_A,
RS_COLUMN_SISO_ANT_B,
RS_COLUMN_MIMO2,
+ RS_COLUMN_LEGACY_ANT_A,
+ RS_COLUMN_LEGACY_ANT_B,
},
.checks = {
rs_mimo_allow,
window->average_tpt = IWL_INVALID_VALUE;
}
-static void rs_rate_scale_clear_tbl_windows(struct iwl_scale_tbl_info *tbl)
+static void rs_rate_scale_clear_tbl_windows(struct iwl_mvm *mvm,
+ struct iwl_scale_tbl_info *tbl)
{
int i;
+ IWL_DEBUG_RATE(mvm, "Clearing up window stats\n");
for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(&tbl->win[i]);
}
return;
}
+#ifdef CPTCFG_MAC80211_DEBUGFS
+ /* Disable last tx check if we are debugging with fixed rate */
+ if (lq_sta->dbg_fixed_rate) {
+ IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n");
+ return;
+ }
+#endif
if (!ieee80211_is_data(hdr->frame_control) ||
info->flags & IEEE80211_TX_CTL_NO_ACK)
return;
mac_index++;
}
+ if (time_after(jiffies,
+ (unsigned long)(lq_sta->last_tx + RS_IDLE_TIMEOUT))) {
+ int tid;
+ IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
+ for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
+ ieee80211_stop_tx_ba_session(sta, tid);
+
+ iwl_mvm_rs_rate_init(mvm, sta, sband->band, false);
+ return;
+ }
+ lq_sta->last_tx = jiffies;
+
/* Here we actually compare this rate to the latest LQ command */
if ((mac_index < 0) ||
(rate.sgi != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
lq_sta->visited_columns = 0;
}
+static int rs_get_max_allowed_rate(struct iwl_lq_sta *lq_sta,
+ const struct rs_tx_column *column)
+{
+ switch (column->mode) {
+ case RS_LEGACY:
+ return lq_sta->max_legacy_rate_idx;
+ case RS_SISO:
+ return lq_sta->max_siso_rate_idx;
+ case RS_MIMO2:
+ return lq_sta->max_mimo2_rate_idx;
+ default:
+ WARN_ON_ONCE(1);
+ }
+
+ return lq_sta->max_legacy_rate_idx;
+}
+
static const u16 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta,
- const struct rs_tx_column *column,
- u32 bw)
+ const struct rs_tx_column *column,
+ u32 bw)
{
/* Used to choose among HT tables */
const u16 (*ht_tbl_pointer)[IWL_RATE_COUNT];
IWL_DEBUG_RATE(mvm,
"LQ: stay in table clear win\n");
- rs_rate_scale_clear_tbl_windows(tbl);
+ rs_rate_scale_clear_tbl_windows(mvm, tbl);
}
}
* bitmaps and stats in active table (this will become the new
* "search" table). */
if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) {
- IWL_DEBUG_RATE(mvm, "Clearing up window stats\n");
- rs_rate_scale_clear_tbl_windows(tbl);
+ rs_rate_scale_clear_tbl_windows(mvm, tbl);
}
}
}
struct ieee80211_sta *sta,
struct iwl_scale_tbl_info *tbl)
{
- int i, j, n;
+ int i, j, max_rate;
enum rs_column next_col_id;
const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column];
const struct rs_tx_column *next_col;
allow_column_func_t allow_func;
u8 valid_ants = mvm->fw->valid_tx_ant;
const u16 *expected_tpt_tbl;
- s32 tpt, max_expected_tpt;
+ u16 tpt, max_expected_tpt;
for (i = 0; i < MAX_NEXT_COLUMNS; i++) {
next_col_id = curr_col->next_columns[i];
if (WARN_ON_ONCE(!expected_tpt_tbl))
continue;
- max_expected_tpt = 0;
- for (n = 0; n < IWL_RATE_COUNT; n++)
- if (expected_tpt_tbl[n] > max_expected_tpt)
- max_expected_tpt = expected_tpt_tbl[n];
+ max_rate = rs_get_max_allowed_rate(lq_sta, next_col);
+ if (WARN_ON_ONCE(max_rate == IWL_RATE_INVALID))
+ continue;
+ max_expected_tpt = expected_tpt_tbl[max_rate];
if (tpt >= max_expected_tpt) {
IWL_DEBUG_RATE(mvm,
"Skip column %d: can't beat current TPT. Max expected %d current %d\n",
continue;
}
+ IWL_DEBUG_RATE(mvm,
+ "Found potential column %d. Max expected %d current %d\n",
+ next_col_id, max_expected_tpt, tpt);
break;
}
if (i == MAX_NEXT_COLUMNS)
return RS_COLUMN_INVALID;
- IWL_DEBUG_RATE(mvm, "Found potential column %d\n", next_col_id);
-
return next_col_id;
}
{
enum rs_action action = RS_ACTION_STAY;
- /* Too many failures, decrease rate */
if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) {
IWL_DEBUG_RATE(mvm,
- "decrease rate because of low SR\n");
- action = RS_ACTION_DOWNSCALE;
- /* No throughput measured yet for adjacent rates; try increase. */
- } else if ((low_tpt == IWL_INVALID_VALUE) &&
- (high_tpt == IWL_INVALID_VALUE)) {
- if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) {
- IWL_DEBUG_RATE(mvm,
- "Good SR and no high rate measurement. "
- "Increase rate\n");
- action = RS_ACTION_UPSCALE;
- } else if (low != IWL_RATE_INVALID) {
- IWL_DEBUG_RATE(mvm,
- "Remain in current rate\n");
- action = RS_ACTION_STAY;
- }
+ "Decrease rate because of low SR\n");
+ return RS_ACTION_DOWNSCALE;
}
- /* Both adjacent throughputs are measured, but neither one has better
- * throughput; we're using the best rate, don't change it!
- */
- else if ((low_tpt != IWL_INVALID_VALUE) &&
- (high_tpt != IWL_INVALID_VALUE) &&
- (low_tpt < current_tpt) &&
- (high_tpt < current_tpt)) {
+ if ((low_tpt == IWL_INVALID_VALUE) &&
+ (high_tpt == IWL_INVALID_VALUE) &&
+ (high != IWL_RATE_INVALID)) {
IWL_DEBUG_RATE(mvm,
- "Both high and low are worse. "
- "Maintain rate\n");
- action = RS_ACTION_STAY;
+ "No data about high/low rates. Increase rate\n");
+ return RS_ACTION_UPSCALE;
}
- /* At least one adjacent rate's throughput is measured,
- * and may have better performance.
- */
- else {
- /* Higher adjacent rate's throughput is measured */
- if (high_tpt != IWL_INVALID_VALUE) {
- /* Higher rate has better throughput */
- if (high_tpt > current_tpt &&
- sr >= IWL_RATE_INCREASE_TH) {
- IWL_DEBUG_RATE(mvm,
- "Higher rate is better and good "
- "SR. Increate rate\n");
- action = RS_ACTION_UPSCALE;
- } else {
- IWL_DEBUG_RATE(mvm,
- "Higher rate isn't better OR "
- "no good SR. Maintain rate\n");
- action = RS_ACTION_STAY;
- }
+ if ((high_tpt == IWL_INVALID_VALUE) &&
+ (high != IWL_RATE_INVALID) &&
+ (low_tpt != IWL_INVALID_VALUE) &&
+ (low_tpt < current_tpt)) {
+ IWL_DEBUG_RATE(mvm,
+ "No data about high rate and low rate is worse. Increase rate\n");
+ return RS_ACTION_UPSCALE;
+ }
- /* Lower adjacent rate's throughput is measured */
- } else if (low_tpt != IWL_INVALID_VALUE) {
- /* Lower rate has better throughput */
- if (low_tpt > current_tpt) {
- IWL_DEBUG_RATE(mvm,
- "Lower rate is better. "
- "Decrease rate\n");
- action = RS_ACTION_DOWNSCALE;
- } else if (sr >= IWL_RATE_INCREASE_TH) {
- IWL_DEBUG_RATE(mvm,
- "Lower rate isn't better and "
- "good SR. Increase rate\n");
- action = RS_ACTION_UPSCALE;
- }
- }
+ if ((high_tpt != IWL_INVALID_VALUE) &&
+ (high_tpt > current_tpt)) {
+ IWL_DEBUG_RATE(mvm,
+ "Higher rate is better. Increate rate\n");
+ return RS_ACTION_UPSCALE;
}
- /* Sanity check; asked for decrease, but success rate or throughput
- * has been good at old rate. Don't change it.
- */
- if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID) &&
- ((sr > IWL_RATE_HIGH_TH) ||
- (current_tpt > (100 * tbl->expected_tpt[low])))) {
+ if ((low_tpt != IWL_INVALID_VALUE) &&
+ (high_tpt != IWL_INVALID_VALUE) &&
+ (low_tpt < current_tpt) &&
+ (high_tpt < current_tpt)) {
+ IWL_DEBUG_RATE(mvm,
+ "Both high and low are worse. Maintain rate\n");
+ return RS_ACTION_STAY;
+ }
+
+ if ((low_tpt != IWL_INVALID_VALUE) &&
+ (low_tpt > current_tpt)) {
+ IWL_DEBUG_RATE(mvm,
+ "Lower rate is better\n");
+ action = RS_ACTION_DOWNSCALE;
+ goto out;
+ }
+
+ if ((low_tpt == IWL_INVALID_VALUE) &&
+ (low != IWL_RATE_INVALID)) {
IWL_DEBUG_RATE(mvm,
- "Sanity check failed. Maintain rate\n");
- action = RS_ACTION_STAY;
+ "No data about lower rate\n");
+ action = RS_ACTION_DOWNSCALE;
+ goto out;
+ }
+
+ IWL_DEBUG_RATE(mvm, "Maintain rate\n");
+
+out:
+ if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) {
+ if (sr >= RS_SR_NO_DECREASE) {
+ IWL_DEBUG_RATE(mvm,
+ "SR is above NO DECREASE. Avoid downscale\n");
+ action = RS_ACTION_STAY;
+ } else if (current_tpt > (100 * tbl->expected_tpt[low])) {
+ IWL_DEBUG_RATE(mvm,
+ "Current TPT is higher than max expected in low rate. Avoid downscale\n");
+ action = RS_ACTION_STAY;
+ } else {
+ IWL_DEBUG_RATE(mvm, "Decrease rate\n");
+ }
}
return action;
"Aggregation changed: prev %d current %d. Update expected TPT table\n",
prev_agg, lq_sta->is_agg);
rs_set_expected_tpt_table(lq_sta, tbl);
+ rs_rate_scale_clear_tbl_windows(mvm, tbl);
}
/* current tx rate */
if (lq_sta->search_better_tbl) {
/* Access the "search" table, clear its history. */
tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
- rs_rate_scale_clear_tbl_windows(tbl);
+ rs_rate_scale_clear_tbl_windows(mvm, tbl);
/* Use new "search" start rate */
index = tbl->rate.index;
* stay with best antenna legacy modulation for a while
* before next round of mode comparisons. */
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
- if (is_legacy(&tbl1->rate) && !sta->ht_cap.ht_supported) {
+ if (is_legacy(&tbl1->rate)) {
IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
+
+ if (tid != IWL_MAX_TID_COUNT) {
+ tid_data = &sta_priv->tid_data[tid];
+ if (tid_data->state != IWL_AGG_OFF) {
+ IWL_DEBUG_RATE(mvm,
+ "Stop aggregation on tid %d\n",
+ tid);
+ ieee80211_stop_tx_ba_session(sta, tid);
+ }
+ }
rs_set_stay_in_table(mvm, 1, lq_sta);
} else {
/* If we're in an HT mode, and all 3 mode switch actions
lq_sta->lq.sta_id = sta_priv->sta_id;
for (j = 0; j < LQ_SIZE; j++)
- rs_rate_scale_clear_tbl_windows(&lq_sta->lq_info[j]);
+ rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]);
lq_sta->flush_timer = 0;
+ lq_sta->last_tx = jiffies;
IWL_DEBUG_RATE(mvm,
"LQ: *** rate scale station global init for station %d ***\n",
lq_sta->is_vht = true;
}
- IWL_DEBUG_RATE(mvm,
- "SISO-RATE=%X MIMO2-RATE=%X VHT=%d\n",
+ lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate,
+ BITS_PER_LONG);
+ lq_sta->max_siso_rate_idx = find_last_bit(&lq_sta->active_siso_rate,
+ BITS_PER_LONG);
+ lq_sta->max_mimo2_rate_idx = find_last_bit(&lq_sta->active_mimo2_rate,
+ BITS_PER_LONG);
+
+ IWL_DEBUG_RATE(mvm, "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d\n",
+ lq_sta->active_legacy_rate,
lq_sta->active_siso_rate,
lq_sta->active_mimo2_rate,
lq_sta->is_vht);
+ IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n",
+ lq_sta->max_legacy_rate_idx,
+ lq_sta->max_siso_rate_idx,
+ lq_sta->max_mimo2_rate_idx);
/* These values will be overridden later */
lq_sta->lq.single_stream_ant_msk =
if (is_siso(&rate)) {
num_rates = RS_SECONDARY_SISO_NUM_RATES;
num_retries = RS_SECONDARY_SISO_RETRIES;
+ lq_cmd->mimo_delim = index;
} else if (is_legacy(&rate)) {
num_rates = RS_SECONDARY_LEGACY_NUM_RATES;
num_retries = RS_LEGACY_RETRIES_PER_RATE;
return -ENOMEM;
desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
- desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
+ desc += sprintf(buff+desc, "failed=%d success=%d rate=0%lX\n",
lq_sta->total_failed, lq_sta->total_success,
lq_sta->active_legacy_rate);
desc += sprintf(buff+desc, "fixed rate 0x%X\n",
#define IWL_RATE_HIGH_TH 10880 /* 85% */
#define IWL_RATE_INCREASE_TH 6400 /* 50% */
#define RS_SR_FORCE_DECREASE 1920 /* 15% */
+#define RS_SR_NO_DECREASE 10880 /* 85% */
#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
u32 visited_columns; /* Bitmask marking which Tx columns were
* explored during a search cycle
*/
+ u64 last_tx;
bool is_vht;
enum ieee80211_band band;
/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
- u16 active_legacy_rate;
- u16 active_siso_rate;
- u16 active_mimo2_rate;
+ unsigned long active_legacy_rate;
+ unsigned long active_siso_rate;
+ unsigned long active_mimo2_rate;
+
+ /* Highest rate per Tx mode */
+ u8 max_legacy_rate_idx;
+ u8 max_siso_rate_idx;
+ u8 max_mimo2_rate_idx;
+
s8 max_rate_idx; /* Max rate set by user */
u8 missed_rate_counter;
return -EINVAL;
if (changed_vif->type != NL80211_IFTYPE_STATION) {
new_state = SF_UNINIT;
- } else if (changed_vif->bss_conf.assoc) {
+ } else if (changed_vif->bss_conf.assoc &&
+ changed_vif->bss_conf.dtim_period) {
mvmvif = iwl_mvm_vif_from_mac80211(changed_vif);
sta_id = mvmvif->ap_sta_id;
new_state = SF_FULL_ON;
{IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)},
{IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)},
+ {IWL_PCI_DEVICE(0x095A, 0x5102, iwl7265_n_cfg)},
{IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x095A, 0x9200, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)},
while ((skb = skb_dequeue(&adapter->usb_rx_data_q)))
mwifiex_handle_rx_packet(adapter, skb);
+ /* Check for event */
+ if (adapter->event_received) {
+ adapter->event_received = false;
+ mwifiex_process_event(adapter);
+ }
+
/* Check for Cmd Resp */
if (adapter->cmd_resp_received) {
adapter->cmd_resp_received = false;
}
}
- /* Check for event */
- if (adapter->event_received) {
- adapter->event_received = false;
- mwifiex_process_event(adapter);
- }
-
/* Check if we need to confirm Sleep Request
received previously */
if (adapter->ps_state == PS_STATE_PRE_SLEEP) {
int status;
/* Wait for completion */
- status = wait_event_interruptible(adapter->cmd_wait_q.wait,
- *(cmd_queued->condition));
- if (status) {
+ status = wait_event_interruptible_timeout(adapter->cmd_wait_q.wait,
+ *(cmd_queued->condition),
+ (12 * HZ));
+ if (status <= 0) {
dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status);
mwifiex_cancel_all_pending_cmd(adapter);
return status;
bool recontend_queue = false;
u32 q_len = 0;
u8 q_num = INVALID_QUEUE;
- u8 ii, min = 0;
+ u8 ii = 0, min = 0;
if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) {
if (!common->mgmt_q_block)
rsi_dbg(MGMT_TX_ZONE,
"%s: Sending scan req frame\n", __func__);
- skb = dev_alloc_skb(FRAME_DESC_SZ);
- if (!skb) {
- rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
- __func__);
- return -ENOMEM;
- }
-
- memset(skb->data, 0, FRAME_DESC_SZ);
- mgmt_frame = (struct rsi_mac_frame *)skb->data;
-
if (common->band == IEEE80211_BAND_5GHZ) {
if ((channel >= 36) && (channel <= 64))
channel = ((channel - 32) / 4);
}
}
+ skb = dev_alloc_skb(FRAME_DESC_SZ);
+ if (!skb) {
+ rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ memset(skb->data, 0, FRAME_DESC_SZ);
+ mgmt_frame = (struct rsi_mac_frame *)skb->data;
+
mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
mgmt_frame->desc_word[1] = cpu_to_le16(SCAN_REQUEST);
mgmt_frame->desc_word[4] = cpu_to_le16(channel);
if (!selected_rates) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n",
__func__);
+ dev_kfree_skb(skb);
return -ENOMEM;
}
/* bitmap of inactive stations (by HLID) */
__le32 inactive_sta_bitmap;
+
+ /* rx BA win size indicated by RX_BA_WIN_SIZE_CHANGE_EVENT_ID */
+ u8 rx_ba_role_id;
+ u8 rx_ba_link_id;
+ u8 rx_ba_win_size;
+ u8 padding;
+
+ /* smart config */
+ u8 sc_ssid_len;
+ u8 sc_pwd_len;
+ u8 sc_token_len;
+ u8 padding1;
+ u8 sc_ssid[32];
+ u8 sc_pwd[32];
+ u8 sc_token[32];
+
+ /* smart config sync channel */
+ u8 sc_sync_channel;
+ u8 sc_sync_band;
+ u8 padding2[2];
} __packed;
int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
void wlcore_event_dummy_packet(struct wl1271 *wl)
{
+ if (wl->plt) {
+ wl1271_info("Got DUMMY_PACKET event in PLT mode. FW bug, ignoring.");
+ return;
+ }
+
wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");
wl1271_tx_dummy_packet(wl);
}
next = &(*next)->next;
}
raw_spin_unlock_irqrestore(&devtree_lock, flags);
- if (rc)
- return rc;
+ if (!found)
+ return -ENODEV;
/* Update the sysfs attribute */
- if (oldprop)
- sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
+ sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
__of_add_property_sysfs(np, newprop);
- if (!found)
- return -ENODEV;
-
return 0;
}
* in /reserved-memory matches the values supported by the current implementation,
* also check if ranges property has been provided
*/
-static int __reserved_mem_check_root(unsigned long node)
+static int __init __reserved_mem_check_root(unsigned long node)
{
__be32 *prop;
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of_pci.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
{
struct pci_sys_data *sys = dev->bus->sysdata;
struct rcar_pci_priv *priv = sys->private_data;
+ int irq;
+
+ irq = of_irq_parse_and_map_pci(dev, slot, pin);
+ if (!irq)
+ irq = priv->irq;
- return priv->irq;
+ return irq;
}
#ifdef CONFIG_PCI_DEBUG
static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
struct tegra_pcie *pcie = sys_to_pcie(pdev->bus->sysdata);
+ int irq;
tegra_cpuidle_pcie_irqs_in_use();
- return pcie->irq;
+ irq = of_irq_parse_and_map_pci(pdev, slot, pin);
+ if (!irq)
+ irq = pcie->irq;
+
+ return irq;
}
static void tegra_pcie_add_bus(struct pci_bus *bus)
#include <linux/module.h>
#include <linux/msi.h>
#include <linux/of_address.h>
+#include <linux/of_pci.h>
#include <linux/pci.h>
#include <linux/pci_regs.h>
#include <linux/types.h>
dw_pci.nr_controllers = 1;
dw_pci.private_data = (void **)&pp;
- pci_common_init(&dw_pci);
+ pci_common_init_dev(pp->dev, &dw_pci);
pci_assign_unassigned_resources();
#ifdef CONFIG_PCI_DOMAINS
dw_pci.domain++;
dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
PCIE_ATU_VIEWPORT);
dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1);
- dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
dw_pcie_writel_rc(pp, pp->cfg1_base, PCIE_ATU_LOWER_BASE);
dw_pcie_writel_rc(pp, (pp->cfg1_base >> 32), PCIE_ATU_UPPER_BASE);
dw_pcie_writel_rc(pp, pp->cfg1_base + pp->config.cfg1_size - 1,
PCIE_ATU_LIMIT);
dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET);
dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET);
+ dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
}
static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
PCIE_ATU_VIEWPORT);
dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1);
- dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE);
dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE);
dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1,
dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET);
dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr),
PCIE_ATU_UPPER_TARGET);
+ dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
}
static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
PCIE_ATU_VIEWPORT);
dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1);
- dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE);
dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE);
dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1,
dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET);
dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr),
PCIE_ATU_UPPER_TARGET);
+ dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
}
static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
if (pp) {
pp->root_bus_nr = sys->busnr;
- bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops,
+ bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops,
sys, &sys->resources);
} else {
bus = NULL;
static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
+ int irq;
+
+ irq = of_irq_parse_and_map_pci(dev, slot, pin);
+ if (!irq)
+ irq = pp->irq;
- return pp->irq;
+ return irq;
}
static void dw_pcie_add_bus(struct pci_bus *bus)
u32 membase;
u32 memlimit;
- /* set the number of lines as 4 */
+ /* set the number of lanes */
dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL, &val);
val &= ~PORT_LINK_MODE_MASK;
switch (pp->lanes) {
config OMAP_CONTROL_PHY
tristate "OMAP CONTROL PHY Driver"
+ depends on ARCH_OMAP2PLUS || COMPILE_TEST
help
Enable this to add support for the PHY part present in the control
module. This driver has API to power on the USB2 PHY and to write to
obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o
obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o
obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o
-obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-samsung-usb2.o
-obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
-obj-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
-obj-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
+obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o
+phy-exynos-usb2-y += phy-samsung-usb2.o
+phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
+phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
+phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
class_dev_iter_init(&iter, phy_class, NULL, NULL);
while ((dev = class_dev_iter_next(&iter))) {
phy = to_phy(dev);
+
+ if (!phy->init_data)
+ continue;
count = phy->init_data->num_consumers;
consumers = phy->init_data->consumers;
while (count--) {
select PINMUX
select PINCONF
-config PINCTRL_CAPRI
- bool "Broadcom Capri pinctrl driver"
+config PINCTRL_BCM281XX
+ bool "Broadcom BCM281xx pinctrl driver"
depends on OF
select PINMUX
select PINCONF
select GENERIC_PINCONF
select REGMAP_MMIO
help
- Say Y here to support Broadcom Capri pinctrl driver, which is used for
- the BCM281xx SoC family, including BCM11130, BCM11140, BCM11351,
+ Say Y here to support Broadcom BCM281xx pinctrl driver, which is used
+ for the BCM281xx SoC family, including BCM11130, BCM11140, BCM11351,
BCM28145, and BCM28155 SoCs. This driver requires the pinctrl
framework. GPIO is provided by a separate GPIO driver.
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
-obj-$(CONFIG_PINCTRL_CAPRI) += pinctrl-capri.o
+obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
obj-$(CONFIG_PINCTRL_IMX1_CORE) += pinctrl-imx1-core.o
obj-$(CONFIG_PINCTRL_IMX27) += pinctrl-imx27.o
--- /dev/null
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include "core.h"
+#include "pinctrl-utils.h"
+
+/* BCM281XX Pin Control Registers Definitions */
+
+/* Function Select bits are the same for all pin control registers */
+#define BCM281XX_PIN_REG_F_SEL_MASK 0x0700
+#define BCM281XX_PIN_REG_F_SEL_SHIFT 8
+
+/* Standard pin register */
+#define BCM281XX_STD_PIN_REG_DRV_STR_MASK 0x0007
+#define BCM281XX_STD_PIN_REG_DRV_STR_SHIFT 0
+#define BCM281XX_STD_PIN_REG_INPUT_DIS_MASK 0x0008
+#define BCM281XX_STD_PIN_REG_INPUT_DIS_SHIFT 3
+#define BCM281XX_STD_PIN_REG_SLEW_MASK 0x0010
+#define BCM281XX_STD_PIN_REG_SLEW_SHIFT 4
+#define BCM281XX_STD_PIN_REG_PULL_UP_MASK 0x0020
+#define BCM281XX_STD_PIN_REG_PULL_UP_SHIFT 5
+#define BCM281XX_STD_PIN_REG_PULL_DN_MASK 0x0040
+#define BCM281XX_STD_PIN_REG_PULL_DN_SHIFT 6
+#define BCM281XX_STD_PIN_REG_HYST_MASK 0x0080
+#define BCM281XX_STD_PIN_REG_HYST_SHIFT 7
+
+/* I2C pin register */
+#define BCM281XX_I2C_PIN_REG_INPUT_DIS_MASK 0x0004
+#define BCM281XX_I2C_PIN_REG_INPUT_DIS_SHIFT 2
+#define BCM281XX_I2C_PIN_REG_SLEW_MASK 0x0008
+#define BCM281XX_I2C_PIN_REG_SLEW_SHIFT 3
+#define BCM281XX_I2C_PIN_REG_PULL_UP_STR_MASK 0x0070
+#define BCM281XX_I2C_PIN_REG_PULL_UP_STR_SHIFT 4
+
+/* HDMI pin register */
+#define BCM281XX_HDMI_PIN_REG_INPUT_DIS_MASK 0x0008
+#define BCM281XX_HDMI_PIN_REG_INPUT_DIS_SHIFT 3
+#define BCM281XX_HDMI_PIN_REG_MODE_MASK 0x0010
+#define BCM281XX_HDMI_PIN_REG_MODE_SHIFT 4
+
+/**
+ * bcm281xx_pin_type - types of pin register
+ */
+enum bcm281xx_pin_type {
+ BCM281XX_PIN_TYPE_UNKNOWN = 0,
+ BCM281XX_PIN_TYPE_STD,
+ BCM281XX_PIN_TYPE_I2C,
+ BCM281XX_PIN_TYPE_HDMI,
+};
+
+static enum bcm281xx_pin_type std_pin = BCM281XX_PIN_TYPE_STD;
+static enum bcm281xx_pin_type i2c_pin = BCM281XX_PIN_TYPE_I2C;
+static enum bcm281xx_pin_type hdmi_pin = BCM281XX_PIN_TYPE_HDMI;
+
+/**
+ * bcm281xx_pin_function- define pin function
+ */
+struct bcm281xx_pin_function {
+ const char *name;
+ const char * const *groups;
+ const unsigned ngroups;
+};
+
+/**
+ * bcm281xx_pinctrl_data - Broadcom-specific pinctrl data
+ * @reg_base - base of pinctrl registers
+ */
+struct bcm281xx_pinctrl_data {
+ void __iomem *reg_base;
+
+ /* List of all pins */
+ const struct pinctrl_pin_desc *pins;
+ const unsigned npins;
+
+ const struct bcm281xx_pin_function *functions;
+ const unsigned nfunctions;
+
+ struct regmap *regmap;
+};
+
+/*
+ * Pin number definition. The order here must be the same as defined in the
+ * PADCTRLREG block in the RDB.
+ */
+#define BCM281XX_PIN_ADCSYNC 0
+#define BCM281XX_PIN_BAT_RM 1
+#define BCM281XX_PIN_BSC1_SCL 2
+#define BCM281XX_PIN_BSC1_SDA 3
+#define BCM281XX_PIN_BSC2_SCL 4
+#define BCM281XX_PIN_BSC2_SDA 5
+#define BCM281XX_PIN_CLASSGPWR 6
+#define BCM281XX_PIN_CLK_CX8 7
+#define BCM281XX_PIN_CLKOUT_0 8
+#define BCM281XX_PIN_CLKOUT_1 9
+#define BCM281XX_PIN_CLKOUT_2 10
+#define BCM281XX_PIN_CLKOUT_3 11
+#define BCM281XX_PIN_CLKREQ_IN_0 12
+#define BCM281XX_PIN_CLKREQ_IN_1 13
+#define BCM281XX_PIN_CWS_SYS_REQ1 14
+#define BCM281XX_PIN_CWS_SYS_REQ2 15
+#define BCM281XX_PIN_CWS_SYS_REQ3 16
+#define BCM281XX_PIN_DIGMIC1_CLK 17
+#define BCM281XX_PIN_DIGMIC1_DQ 18
+#define BCM281XX_PIN_DIGMIC2_CLK 19
+#define BCM281XX_PIN_DIGMIC2_DQ 20
+#define BCM281XX_PIN_GPEN13 21
+#define BCM281XX_PIN_GPEN14 22
+#define BCM281XX_PIN_GPEN15 23
+#define BCM281XX_PIN_GPIO00 24
+#define BCM281XX_PIN_GPIO01 25
+#define BCM281XX_PIN_GPIO02 26
+#define BCM281XX_PIN_GPIO03 27
+#define BCM281XX_PIN_GPIO04 28
+#define BCM281XX_PIN_GPIO05 29
+#define BCM281XX_PIN_GPIO06 30
+#define BCM281XX_PIN_GPIO07 31
+#define BCM281XX_PIN_GPIO08 32
+#define BCM281XX_PIN_GPIO09 33
+#define BCM281XX_PIN_GPIO10 34
+#define BCM281XX_PIN_GPIO11 35
+#define BCM281XX_PIN_GPIO12 36
+#define BCM281XX_PIN_GPIO13 37
+#define BCM281XX_PIN_GPIO14 38
+#define BCM281XX_PIN_GPS_PABLANK 39
+#define BCM281XX_PIN_GPS_TMARK 40
+#define BCM281XX_PIN_HDMI_SCL 41
+#define BCM281XX_PIN_HDMI_SDA 42
+#define BCM281XX_PIN_IC_DM 43
+#define BCM281XX_PIN_IC_DP 44
+#define BCM281XX_PIN_KP_COL_IP_0 45
+#define BCM281XX_PIN_KP_COL_IP_1 46
+#define BCM281XX_PIN_KP_COL_IP_2 47
+#define BCM281XX_PIN_KP_COL_IP_3 48
+#define BCM281XX_PIN_KP_ROW_OP_0 49
+#define BCM281XX_PIN_KP_ROW_OP_1 50
+#define BCM281XX_PIN_KP_ROW_OP_2 51
+#define BCM281XX_PIN_KP_ROW_OP_3 52
+#define BCM281XX_PIN_LCD_B_0 53
+#define BCM281XX_PIN_LCD_B_1 54
+#define BCM281XX_PIN_LCD_B_2 55
+#define BCM281XX_PIN_LCD_B_3 56
+#define BCM281XX_PIN_LCD_B_4 57
+#define BCM281XX_PIN_LCD_B_5 58
+#define BCM281XX_PIN_LCD_B_6 59
+#define BCM281XX_PIN_LCD_B_7 60
+#define BCM281XX_PIN_LCD_G_0 61
+#define BCM281XX_PIN_LCD_G_1 62
+#define BCM281XX_PIN_LCD_G_2 63
+#define BCM281XX_PIN_LCD_G_3 64
+#define BCM281XX_PIN_LCD_G_4 65
+#define BCM281XX_PIN_LCD_G_5 66
+#define BCM281XX_PIN_LCD_G_6 67
+#define BCM281XX_PIN_LCD_G_7 68
+#define BCM281XX_PIN_LCD_HSYNC 69
+#define BCM281XX_PIN_LCD_OE 70
+#define BCM281XX_PIN_LCD_PCLK 71
+#define BCM281XX_PIN_LCD_R_0 72
+#define BCM281XX_PIN_LCD_R_1 73
+#define BCM281XX_PIN_LCD_R_2 74
+#define BCM281XX_PIN_LCD_R_3 75
+#define BCM281XX_PIN_LCD_R_4 76
+#define BCM281XX_PIN_LCD_R_5 77
+#define BCM281XX_PIN_LCD_R_6 78
+#define BCM281XX_PIN_LCD_R_7 79
+#define BCM281XX_PIN_LCD_VSYNC 80
+#define BCM281XX_PIN_MDMGPIO0 81
+#define BCM281XX_PIN_MDMGPIO1 82
+#define BCM281XX_PIN_MDMGPIO2 83
+#define BCM281XX_PIN_MDMGPIO3 84
+#define BCM281XX_PIN_MDMGPIO4 85
+#define BCM281XX_PIN_MDMGPIO5 86
+#define BCM281XX_PIN_MDMGPIO6 87
+#define BCM281XX_PIN_MDMGPIO7 88
+#define BCM281XX_PIN_MDMGPIO8 89
+#define BCM281XX_PIN_MPHI_DATA_0 90
+#define BCM281XX_PIN_MPHI_DATA_1 91
+#define BCM281XX_PIN_MPHI_DATA_2 92
+#define BCM281XX_PIN_MPHI_DATA_3 93
+#define BCM281XX_PIN_MPHI_DATA_4 94
+#define BCM281XX_PIN_MPHI_DATA_5 95
+#define BCM281XX_PIN_MPHI_DATA_6 96
+#define BCM281XX_PIN_MPHI_DATA_7 97
+#define BCM281XX_PIN_MPHI_DATA_8 98
+#define BCM281XX_PIN_MPHI_DATA_9 99
+#define BCM281XX_PIN_MPHI_DATA_10 100
+#define BCM281XX_PIN_MPHI_DATA_11 101
+#define BCM281XX_PIN_MPHI_DATA_12 102
+#define BCM281XX_PIN_MPHI_DATA_13 103
+#define BCM281XX_PIN_MPHI_DATA_14 104
+#define BCM281XX_PIN_MPHI_DATA_15 105
+#define BCM281XX_PIN_MPHI_HA0 106
+#define BCM281XX_PIN_MPHI_HAT0 107
+#define BCM281XX_PIN_MPHI_HAT1 108
+#define BCM281XX_PIN_MPHI_HCE0_N 109
+#define BCM281XX_PIN_MPHI_HCE1_N 110
+#define BCM281XX_PIN_MPHI_HRD_N 111
+#define BCM281XX_PIN_MPHI_HWR_N 112
+#define BCM281XX_PIN_MPHI_RUN0 113
+#define BCM281XX_PIN_MPHI_RUN1 114
+#define BCM281XX_PIN_MTX_SCAN_CLK 115
+#define BCM281XX_PIN_MTX_SCAN_DATA 116
+#define BCM281XX_PIN_NAND_AD_0 117
+#define BCM281XX_PIN_NAND_AD_1 118
+#define BCM281XX_PIN_NAND_AD_2 119
+#define BCM281XX_PIN_NAND_AD_3 120
+#define BCM281XX_PIN_NAND_AD_4 121
+#define BCM281XX_PIN_NAND_AD_5 122
+#define BCM281XX_PIN_NAND_AD_6 123
+#define BCM281XX_PIN_NAND_AD_7 124
+#define BCM281XX_PIN_NAND_ALE 125
+#define BCM281XX_PIN_NAND_CEN_0 126
+#define BCM281XX_PIN_NAND_CEN_1 127
+#define BCM281XX_PIN_NAND_CLE 128
+#define BCM281XX_PIN_NAND_OEN 129
+#define BCM281XX_PIN_NAND_RDY_0 130
+#define BCM281XX_PIN_NAND_RDY_1 131
+#define BCM281XX_PIN_NAND_WEN 132
+#define BCM281XX_PIN_NAND_WP 133
+#define BCM281XX_PIN_PC1 134
+#define BCM281XX_PIN_PC2 135
+#define BCM281XX_PIN_PMU_INT 136
+#define BCM281XX_PIN_PMU_SCL 137
+#define BCM281XX_PIN_PMU_SDA 138
+#define BCM281XX_PIN_RFST2G_MTSLOTEN3G 139
+#define BCM281XX_PIN_RGMII_0_RX_CTL 140
+#define BCM281XX_PIN_RGMII_0_RXC 141
+#define BCM281XX_PIN_RGMII_0_RXD_0 142
+#define BCM281XX_PIN_RGMII_0_RXD_1 143
+#define BCM281XX_PIN_RGMII_0_RXD_2 144
+#define BCM281XX_PIN_RGMII_0_RXD_3 145
+#define BCM281XX_PIN_RGMII_0_TX_CTL 146
+#define BCM281XX_PIN_RGMII_0_TXC 147
+#define BCM281XX_PIN_RGMII_0_TXD_0 148
+#define BCM281XX_PIN_RGMII_0_TXD_1 149
+#define BCM281XX_PIN_RGMII_0_TXD_2 150
+#define BCM281XX_PIN_RGMII_0_TXD_3 151
+#define BCM281XX_PIN_RGMII_1_RX_CTL 152
+#define BCM281XX_PIN_RGMII_1_RXC 153
+#define BCM281XX_PIN_RGMII_1_RXD_0 154
+#define BCM281XX_PIN_RGMII_1_RXD_1 155
+#define BCM281XX_PIN_RGMII_1_RXD_2 156
+#define BCM281XX_PIN_RGMII_1_RXD_3 157
+#define BCM281XX_PIN_RGMII_1_TX_CTL 158
+#define BCM281XX_PIN_RGMII_1_TXC 159
+#define BCM281XX_PIN_RGMII_1_TXD_0 160
+#define BCM281XX_PIN_RGMII_1_TXD_1 161
+#define BCM281XX_PIN_RGMII_1_TXD_2 162
+#define BCM281XX_PIN_RGMII_1_TXD_3 163
+#define BCM281XX_PIN_RGMII_GPIO_0 164
+#define BCM281XX_PIN_RGMII_GPIO_1 165
+#define BCM281XX_PIN_RGMII_GPIO_2 166
+#define BCM281XX_PIN_RGMII_GPIO_3 167
+#define BCM281XX_PIN_RTXDATA2G_TXDATA3G1 168
+#define BCM281XX_PIN_RTXEN2G_TXDATA3G2 169
+#define BCM281XX_PIN_RXDATA3G0 170
+#define BCM281XX_PIN_RXDATA3G1 171
+#define BCM281XX_PIN_RXDATA3G2 172
+#define BCM281XX_PIN_SDIO1_CLK 173
+#define BCM281XX_PIN_SDIO1_CMD 174
+#define BCM281XX_PIN_SDIO1_DATA_0 175
+#define BCM281XX_PIN_SDIO1_DATA_1 176
+#define BCM281XX_PIN_SDIO1_DATA_2 177
+#define BCM281XX_PIN_SDIO1_DATA_3 178
+#define BCM281XX_PIN_SDIO4_CLK 179
+#define BCM281XX_PIN_SDIO4_CMD 180
+#define BCM281XX_PIN_SDIO4_DATA_0 181
+#define BCM281XX_PIN_SDIO4_DATA_1 182
+#define BCM281XX_PIN_SDIO4_DATA_2 183
+#define BCM281XX_PIN_SDIO4_DATA_3 184
+#define BCM281XX_PIN_SIM_CLK 185
+#define BCM281XX_PIN_SIM_DATA 186
+#define BCM281XX_PIN_SIM_DET 187
+#define BCM281XX_PIN_SIM_RESETN 188
+#define BCM281XX_PIN_SIM2_CLK 189
+#define BCM281XX_PIN_SIM2_DATA 190
+#define BCM281XX_PIN_SIM2_DET 191
+#define BCM281XX_PIN_SIM2_RESETN 192
+#define BCM281XX_PIN_SRI_C 193
+#define BCM281XX_PIN_SRI_D 194
+#define BCM281XX_PIN_SRI_E 195
+#define BCM281XX_PIN_SSP_EXTCLK 196
+#define BCM281XX_PIN_SSP0_CLK 197
+#define BCM281XX_PIN_SSP0_FS 198
+#define BCM281XX_PIN_SSP0_RXD 199
+#define BCM281XX_PIN_SSP0_TXD 200
+#define BCM281XX_PIN_SSP2_CLK 201
+#define BCM281XX_PIN_SSP2_FS_0 202
+#define BCM281XX_PIN_SSP2_FS_1 203
+#define BCM281XX_PIN_SSP2_FS_2 204
+#define BCM281XX_PIN_SSP2_FS_3 205
+#define BCM281XX_PIN_SSP2_RXD_0 206
+#define BCM281XX_PIN_SSP2_RXD_1 207
+#define BCM281XX_PIN_SSP2_TXD_0 208
+#define BCM281XX_PIN_SSP2_TXD_1 209
+#define BCM281XX_PIN_SSP3_CLK 210
+#define BCM281XX_PIN_SSP3_FS 211
+#define BCM281XX_PIN_SSP3_RXD 212
+#define BCM281XX_PIN_SSP3_TXD 213
+#define BCM281XX_PIN_SSP4_CLK 214
+#define BCM281XX_PIN_SSP4_FS 215
+#define BCM281XX_PIN_SSP4_RXD 216
+#define BCM281XX_PIN_SSP4_TXD 217
+#define BCM281XX_PIN_SSP5_CLK 218
+#define BCM281XX_PIN_SSP5_FS 219
+#define BCM281XX_PIN_SSP5_RXD 220
+#define BCM281XX_PIN_SSP5_TXD 221
+#define BCM281XX_PIN_SSP6_CLK 222
+#define BCM281XX_PIN_SSP6_FS 223
+#define BCM281XX_PIN_SSP6_RXD 224
+#define BCM281XX_PIN_SSP6_TXD 225
+#define BCM281XX_PIN_STAT_1 226
+#define BCM281XX_PIN_STAT_2 227
+#define BCM281XX_PIN_SYSCLKEN 228
+#define BCM281XX_PIN_TRACECLK 229
+#define BCM281XX_PIN_TRACEDT00 230
+#define BCM281XX_PIN_TRACEDT01 231
+#define BCM281XX_PIN_TRACEDT02 232
+#define BCM281XX_PIN_TRACEDT03 233
+#define BCM281XX_PIN_TRACEDT04 234
+#define BCM281XX_PIN_TRACEDT05 235
+#define BCM281XX_PIN_TRACEDT06 236
+#define BCM281XX_PIN_TRACEDT07 237
+#define BCM281XX_PIN_TRACEDT08 238
+#define BCM281XX_PIN_TRACEDT09 239
+#define BCM281XX_PIN_TRACEDT10 240
+#define BCM281XX_PIN_TRACEDT11 241
+#define BCM281XX_PIN_TRACEDT12 242
+#define BCM281XX_PIN_TRACEDT13 243
+#define BCM281XX_PIN_TRACEDT14 244
+#define BCM281XX_PIN_TRACEDT15 245
+#define BCM281XX_PIN_TXDATA3G0 246
+#define BCM281XX_PIN_TXPWRIND 247
+#define BCM281XX_PIN_UARTB1_UCTS 248
+#define BCM281XX_PIN_UARTB1_URTS 249
+#define BCM281XX_PIN_UARTB1_URXD 250
+#define BCM281XX_PIN_UARTB1_UTXD 251
+#define BCM281XX_PIN_UARTB2_URXD 252
+#define BCM281XX_PIN_UARTB2_UTXD 253
+#define BCM281XX_PIN_UARTB3_UCTS 254
+#define BCM281XX_PIN_UARTB3_URTS 255
+#define BCM281XX_PIN_UARTB3_URXD 256
+#define BCM281XX_PIN_UARTB3_UTXD 257
+#define BCM281XX_PIN_UARTB4_UCTS 258
+#define BCM281XX_PIN_UARTB4_URTS 259
+#define BCM281XX_PIN_UARTB4_URXD 260
+#define BCM281XX_PIN_UARTB4_UTXD 261
+#define BCM281XX_PIN_VC_CAM1_SCL 262
+#define BCM281XX_PIN_VC_CAM1_SDA 263
+#define BCM281XX_PIN_VC_CAM2_SCL 264
+#define BCM281XX_PIN_VC_CAM2_SDA 265
+#define BCM281XX_PIN_VC_CAM3_SCL 266
+#define BCM281XX_PIN_VC_CAM3_SDA 267
+
+#define BCM281XX_PIN_DESC(a, b, c) \
+ { .number = a, .name = b, .drv_data = &c##_pin }
+
+/*
+ * Pin description definition. The order here must be the same as defined in
+ * the PADCTRLREG block in the RDB, since the pin number is used as an index
+ * into this array.
+ */
+static const struct pinctrl_pin_desc bcm281xx_pinctrl_pins[] = {
+ BCM281XX_PIN_DESC(BCM281XX_PIN_ADCSYNC, "adcsync", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_BAT_RM, "bat_rm", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_BSC1_SCL, "bsc1_scl", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_BSC1_SDA, "bsc1_sda", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_BSC2_SCL, "bsc2_scl", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_BSC2_SDA, "bsc2_sda", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLASSGPWR, "classgpwr", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLK_CX8, "clk_cx8", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_0, "clkout_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_1, "clkout_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_2, "clkout_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_3, "clkout_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLKREQ_IN_0, "clkreq_in_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLKREQ_IN_1, "clkreq_in_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CWS_SYS_REQ1, "cws_sys_req1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CWS_SYS_REQ2, "cws_sys_req2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CWS_SYS_REQ3, "cws_sys_req3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC1_CLK, "digmic1_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC1_DQ, "digmic1_dq", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC2_CLK, "digmic2_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC2_DQ, "digmic2_dq", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPEN13, "gpen13", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPEN14, "gpen14", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPEN15, "gpen15", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO00, "gpio00", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO01, "gpio01", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO02, "gpio02", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO03, "gpio03", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO04, "gpio04", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO05, "gpio05", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO06, "gpio06", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO07, "gpio07", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO08, "gpio08", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO09, "gpio09", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO10, "gpio10", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO11, "gpio11", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO12, "gpio12", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO13, "gpio13", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO14, "gpio14", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPS_PABLANK, "gps_pablank", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPS_TMARK, "gps_tmark", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_HDMI_SCL, "hdmi_scl", hdmi),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_HDMI_SDA, "hdmi_sda", hdmi),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_IC_DM, "ic_dm", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_IC_DP, "ic_dp", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_0, "kp_col_ip_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_1, "kp_col_ip_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_2, "kp_col_ip_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_3, "kp_col_ip_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_0, "kp_row_op_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_1, "kp_row_op_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_2, "kp_row_op_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_3, "kp_row_op_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_0, "lcd_b_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_1, "lcd_b_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_2, "lcd_b_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_3, "lcd_b_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_4, "lcd_b_4", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_5, "lcd_b_5", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_6, "lcd_b_6", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_7, "lcd_b_7", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_0, "lcd_g_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_1, "lcd_g_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_2, "lcd_g_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_3, "lcd_g_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_4, "lcd_g_4", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_5, "lcd_g_5", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_6, "lcd_g_6", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_7, "lcd_g_7", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_HSYNC, "lcd_hsync", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_OE, "lcd_oe", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_PCLK, "lcd_pclk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_0, "lcd_r_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_1, "lcd_r_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_2, "lcd_r_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_3, "lcd_r_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_4, "lcd_r_4", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_5, "lcd_r_5", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_6, "lcd_r_6", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_7, "lcd_r_7", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_VSYNC, "lcd_vsync", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO0, "mdmgpio0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO1, "mdmgpio1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO2, "mdmgpio2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO3, "mdmgpio3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO4, "mdmgpio4", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO5, "mdmgpio5", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO6, "mdmgpio6", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO7, "mdmgpio7", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO8, "mdmgpio8", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_0, "mphi_data_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_1, "mphi_data_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_2, "mphi_data_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_3, "mphi_data_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_4, "mphi_data_4", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_5, "mphi_data_5", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_6, "mphi_data_6", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_7, "mphi_data_7", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_8, "mphi_data_8", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_9, "mphi_data_9", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_10, "mphi_data_10", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_11, "mphi_data_11", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_12, "mphi_data_12", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_13, "mphi_data_13", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_14, "mphi_data_14", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_15, "mphi_data_15", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HA0, "mphi_ha0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HAT0, "mphi_hat0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HAT1, "mphi_hat1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HCE0_N, "mphi_hce0_n", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HCE1_N, "mphi_hce1_n", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HRD_N, "mphi_hrd_n", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HWR_N, "mphi_hwr_n", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_RUN0, "mphi_run0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_RUN1, "mphi_run1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MTX_SCAN_CLK, "mtx_scan_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MTX_SCAN_DATA, "mtx_scan_data", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_0, "nand_ad_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_1, "nand_ad_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_2, "nand_ad_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_3, "nand_ad_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_4, "nand_ad_4", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_5, "nand_ad_5", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_6, "nand_ad_6", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_7, "nand_ad_7", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_ALE, "nand_ale", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_CEN_0, "nand_cen_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_CEN_1, "nand_cen_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_CLE, "nand_cle", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_OEN, "nand_oen", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_RDY_0, "nand_rdy_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_RDY_1, "nand_rdy_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_WEN, "nand_wen", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_WP, "nand_wp", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_PC1, "pc1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_PC2, "pc2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_PMU_INT, "pmu_int", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_PMU_SCL, "pmu_scl", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_PMU_SDA, "pmu_sda", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RFST2G_MTSLOTEN3G, "rfst2g_mtsloten3g",
+ std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RX_CTL, "rgmii_0_rx_ctl", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXC, "rgmii_0_rxc", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_0, "rgmii_0_rxd_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_1, "rgmii_0_rxd_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_2, "rgmii_0_rxd_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_3, "rgmii_0_rxd_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TX_CTL, "rgmii_0_tx_ctl", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXC, "rgmii_0_txc", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_0, "rgmii_0_txd_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_1, "rgmii_0_txd_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_2, "rgmii_0_txd_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_3, "rgmii_0_txd_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RX_CTL, "rgmii_1_rx_ctl", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXC, "rgmii_1_rxc", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_0, "rgmii_1_rxd_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_1, "rgmii_1_rxd_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_2, "rgmii_1_rxd_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_3, "rgmii_1_rxd_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TX_CTL, "rgmii_1_tx_ctl", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXC, "rgmii_1_txc", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_0, "rgmii_1_txd_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_1, "rgmii_1_txd_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_2, "rgmii_1_txd_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_3, "rgmii_1_txd_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_0, "rgmii_gpio_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_1, "rgmii_gpio_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_2, "rgmii_gpio_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_3, "rgmii_gpio_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RTXDATA2G_TXDATA3G1,
+ "rtxdata2g_txdata3g1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RTXEN2G_TXDATA3G2, "rtxen2g_txdata3g2",
+ std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RXDATA3G0, "rxdata3g0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RXDATA3G1, "rxdata3g1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RXDATA3G2, "rxdata3g2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_CLK, "sdio1_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_CMD, "sdio1_cmd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_0, "sdio1_data_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_1, "sdio1_data_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_2, "sdio1_data_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_3, "sdio1_data_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_CLK, "sdio4_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_CMD, "sdio4_cmd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_0, "sdio4_data_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_1, "sdio4_data_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_2, "sdio4_data_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_3, "sdio4_data_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_CLK, "sim_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_DATA, "sim_data", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_DET, "sim_det", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_RESETN, "sim_resetn", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_CLK, "sim2_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_DATA, "sim2_data", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_DET, "sim2_det", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_RESETN, "sim2_resetn", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SRI_C, "sri_c", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SRI_D, "sri_d", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SRI_E, "sri_e", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP_EXTCLK, "ssp_extclk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_CLK, "ssp0_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_FS, "ssp0_fs", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_RXD, "ssp0_rxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_TXD, "ssp0_txd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_CLK, "ssp2_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_0, "ssp2_fs_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_1, "ssp2_fs_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_2, "ssp2_fs_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_3, "ssp2_fs_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_RXD_0, "ssp2_rxd_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_RXD_1, "ssp2_rxd_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_TXD_0, "ssp2_txd_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_TXD_1, "ssp2_txd_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_CLK, "ssp3_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_FS, "ssp3_fs", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_RXD, "ssp3_rxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_TXD, "ssp3_txd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_CLK, "ssp4_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_FS, "ssp4_fs", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_RXD, "ssp4_rxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_TXD, "ssp4_txd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_CLK, "ssp5_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_FS, "ssp5_fs", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_RXD, "ssp5_rxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_TXD, "ssp5_txd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_CLK, "ssp6_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_FS, "ssp6_fs", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_RXD, "ssp6_rxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_TXD, "ssp6_txd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_STAT_1, "stat_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_STAT_2, "stat_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SYSCLKEN, "sysclken", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACECLK, "traceclk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT00, "tracedt00", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT01, "tracedt01", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT02, "tracedt02", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT03, "tracedt03", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT04, "tracedt04", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT05, "tracedt05", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT06, "tracedt06", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT07, "tracedt07", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT08, "tracedt08", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT09, "tracedt09", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT10, "tracedt10", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT11, "tracedt11", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT12, "tracedt12", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT13, "tracedt13", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT14, "tracedt14", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT15, "tracedt15", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TXDATA3G0, "txdata3g0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TXPWRIND, "txpwrind", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_UCTS, "uartb1_ucts", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_URTS, "uartb1_urts", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_URXD, "uartb1_urxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_UTXD, "uartb1_utxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB2_URXD, "uartb2_urxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB2_UTXD, "uartb2_utxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_UCTS, "uartb3_ucts", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_URTS, "uartb3_urts", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_URXD, "uartb3_urxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_UTXD, "uartb3_utxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_UCTS, "uartb4_ucts", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_URTS, "uartb4_urts", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_URXD, "uartb4_urxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_UTXD, "uartb4_utxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM1_SCL, "vc_cam1_scl", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM1_SDA, "vc_cam1_sda", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM2_SCL, "vc_cam2_scl", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM2_SDA, "vc_cam2_sda", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM3_SCL, "vc_cam3_scl", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM3_SDA, "vc_cam3_sda", i2c),
+};
+
+static const char * const bcm281xx_alt_groups[] = {
+ "adcsync",
+ "bat_rm",
+ "bsc1_scl",
+ "bsc1_sda",
+ "bsc2_scl",
+ "bsc2_sda",
+ "classgpwr",
+ "clk_cx8",
+ "clkout_0",
+ "clkout_1",
+ "clkout_2",
+ "clkout_3",
+ "clkreq_in_0",
+ "clkreq_in_1",
+ "cws_sys_req1",
+ "cws_sys_req2",
+ "cws_sys_req3",
+ "digmic1_clk",
+ "digmic1_dq",
+ "digmic2_clk",
+ "digmic2_dq",
+ "gpen13",
+ "gpen14",
+ "gpen15",
+ "gpio00",
+ "gpio01",
+ "gpio02",
+ "gpio03",
+ "gpio04",
+ "gpio05",
+ "gpio06",
+ "gpio07",
+ "gpio08",
+ "gpio09",
+ "gpio10",
+ "gpio11",
+ "gpio12",
+ "gpio13",
+ "gpio14",
+ "gps_pablank",
+ "gps_tmark",
+ "hdmi_scl",
+ "hdmi_sda",
+ "ic_dm",
+ "ic_dp",
+ "kp_col_ip_0",
+ "kp_col_ip_1",
+ "kp_col_ip_2",
+ "kp_col_ip_3",
+ "kp_row_op_0",
+ "kp_row_op_1",
+ "kp_row_op_2",
+ "kp_row_op_3",
+ "lcd_b_0",
+ "lcd_b_1",
+ "lcd_b_2",
+ "lcd_b_3",
+ "lcd_b_4",
+ "lcd_b_5",
+ "lcd_b_6",
+ "lcd_b_7",
+ "lcd_g_0",
+ "lcd_g_1",
+ "lcd_g_2",
+ "lcd_g_3",
+ "lcd_g_4",
+ "lcd_g_5",
+ "lcd_g_6",
+ "lcd_g_7",
+ "lcd_hsync",
+ "lcd_oe",
+ "lcd_pclk",
+ "lcd_r_0",
+ "lcd_r_1",
+ "lcd_r_2",
+ "lcd_r_3",
+ "lcd_r_4",
+ "lcd_r_5",
+ "lcd_r_6",
+ "lcd_r_7",
+ "lcd_vsync",
+ "mdmgpio0",
+ "mdmgpio1",
+ "mdmgpio2",
+ "mdmgpio3",
+ "mdmgpio4",
+ "mdmgpio5",
+ "mdmgpio6",
+ "mdmgpio7",
+ "mdmgpio8",
+ "mphi_data_0",
+ "mphi_data_1",
+ "mphi_data_2",
+ "mphi_data_3",
+ "mphi_data_4",
+ "mphi_data_5",
+ "mphi_data_6",
+ "mphi_data_7",
+ "mphi_data_8",
+ "mphi_data_9",
+ "mphi_data_10",
+ "mphi_data_11",
+ "mphi_data_12",
+ "mphi_data_13",
+ "mphi_data_14",
+ "mphi_data_15",
+ "mphi_ha0",
+ "mphi_hat0",
+ "mphi_hat1",
+ "mphi_hce0_n",
+ "mphi_hce1_n",
+ "mphi_hrd_n",
+ "mphi_hwr_n",
+ "mphi_run0",
+ "mphi_run1",
+ "mtx_scan_clk",
+ "mtx_scan_data",
+ "nand_ad_0",
+ "nand_ad_1",
+ "nand_ad_2",
+ "nand_ad_3",
+ "nand_ad_4",
+ "nand_ad_5",
+ "nand_ad_6",
+ "nand_ad_7",
+ "nand_ale",
+ "nand_cen_0",
+ "nand_cen_1",
+ "nand_cle",
+ "nand_oen",
+ "nand_rdy_0",
+ "nand_rdy_1",
+ "nand_wen",
+ "nand_wp",
+ "pc1",
+ "pc2",
+ "pmu_int",
+ "pmu_scl",
+ "pmu_sda",
+ "rfst2g_mtsloten3g",
+ "rgmii_0_rx_ctl",
+ "rgmii_0_rxc",
+ "rgmii_0_rxd_0",
+ "rgmii_0_rxd_1",
+ "rgmii_0_rxd_2",
+ "rgmii_0_rxd_3",
+ "rgmii_0_tx_ctl",
+ "rgmii_0_txc",
+ "rgmii_0_txd_0",
+ "rgmii_0_txd_1",
+ "rgmii_0_txd_2",
+ "rgmii_0_txd_3",
+ "rgmii_1_rx_ctl",
+ "rgmii_1_rxc",
+ "rgmii_1_rxd_0",
+ "rgmii_1_rxd_1",
+ "rgmii_1_rxd_2",
+ "rgmii_1_rxd_3",
+ "rgmii_1_tx_ctl",
+ "rgmii_1_txc",
+ "rgmii_1_txd_0",
+ "rgmii_1_txd_1",
+ "rgmii_1_txd_2",
+ "rgmii_1_txd_3",
+ "rgmii_gpio_0",
+ "rgmii_gpio_1",
+ "rgmii_gpio_2",
+ "rgmii_gpio_3",
+ "rtxdata2g_txdata3g1",
+ "rtxen2g_txdata3g2",
+ "rxdata3g0",
+ "rxdata3g1",
+ "rxdata3g2",
+ "sdio1_clk",
+ "sdio1_cmd",
+ "sdio1_data_0",
+ "sdio1_data_1",
+ "sdio1_data_2",
+ "sdio1_data_3",
+ "sdio4_clk",
+ "sdio4_cmd",
+ "sdio4_data_0",
+ "sdio4_data_1",
+ "sdio4_data_2",
+ "sdio4_data_3",
+ "sim_clk",
+ "sim_data",
+ "sim_det",
+ "sim_resetn",
+ "sim2_clk",
+ "sim2_data",
+ "sim2_det",
+ "sim2_resetn",
+ "sri_c",
+ "sri_d",
+ "sri_e",
+ "ssp_extclk",
+ "ssp0_clk",
+ "ssp0_fs",
+ "ssp0_rxd",
+ "ssp0_txd",
+ "ssp2_clk",
+ "ssp2_fs_0",
+ "ssp2_fs_1",
+ "ssp2_fs_2",
+ "ssp2_fs_3",
+ "ssp2_rxd_0",
+ "ssp2_rxd_1",
+ "ssp2_txd_0",
+ "ssp2_txd_1",
+ "ssp3_clk",
+ "ssp3_fs",
+ "ssp3_rxd",
+ "ssp3_txd",
+ "ssp4_clk",
+ "ssp4_fs",
+ "ssp4_rxd",
+ "ssp4_txd",
+ "ssp5_clk",
+ "ssp5_fs",
+ "ssp5_rxd",
+ "ssp5_txd",
+ "ssp6_clk",
+ "ssp6_fs",
+ "ssp6_rxd",
+ "ssp6_txd",
+ "stat_1",
+ "stat_2",
+ "sysclken",
+ "traceclk",
+ "tracedt00",
+ "tracedt01",
+ "tracedt02",
+ "tracedt03",
+ "tracedt04",
+ "tracedt05",
+ "tracedt06",
+ "tracedt07",
+ "tracedt08",
+ "tracedt09",
+ "tracedt10",
+ "tracedt11",
+ "tracedt12",
+ "tracedt13",
+ "tracedt14",
+ "tracedt15",
+ "txdata3g0",
+ "txpwrind",
+ "uartb1_ucts",
+ "uartb1_urts",
+ "uartb1_urxd",
+ "uartb1_utxd",
+ "uartb2_urxd",
+ "uartb2_utxd",
+ "uartb3_ucts",
+ "uartb3_urts",
+ "uartb3_urxd",
+ "uartb3_utxd",
+ "uartb4_ucts",
+ "uartb4_urts",
+ "uartb4_urxd",
+ "uartb4_utxd",
+ "vc_cam1_scl",
+ "vc_cam1_sda",
+ "vc_cam2_scl",
+ "vc_cam2_sda",
+ "vc_cam3_scl",
+ "vc_cam3_sda",
+};
+
+/* Every pin can implement all ALT1-ALT4 functions */
+#define BCM281XX_PIN_FUNCTION(fcn_name) \
+{ \
+ .name = #fcn_name, \
+ .groups = bcm281xx_alt_groups, \
+ .ngroups = ARRAY_SIZE(bcm281xx_alt_groups), \
+}
+
+static const struct bcm281xx_pin_function bcm281xx_functions[] = {
+ BCM281XX_PIN_FUNCTION(alt1),
+ BCM281XX_PIN_FUNCTION(alt2),
+ BCM281XX_PIN_FUNCTION(alt3),
+ BCM281XX_PIN_FUNCTION(alt4),
+};
+
+static struct bcm281xx_pinctrl_data bcm281xx_pinctrl = {
+ .pins = bcm281xx_pinctrl_pins,
+ .npins = ARRAY_SIZE(bcm281xx_pinctrl_pins),
+ .functions = bcm281xx_functions,
+ .nfunctions = ARRAY_SIZE(bcm281xx_functions),
+};
+
+static inline enum bcm281xx_pin_type pin_type_get(struct pinctrl_dev *pctldev,
+ unsigned pin)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ if (pin >= pdata->npins)
+ return BCM281XX_PIN_TYPE_UNKNOWN;
+
+ return *(enum bcm281xx_pin_type *)(pdata->pins[pin].drv_data);
+}
+
+#define BCM281XX_PIN_SHIFT(type, param) \
+ (BCM281XX_ ## type ## _PIN_REG_ ## param ## _SHIFT)
+
+#define BCM281XX_PIN_MASK(type, param) \
+ (BCM281XX_ ## type ## _PIN_REG_ ## param ## _MASK)
+
+/*
+ * This helper function is used to build up the value and mask used to write to
+ * a pin register, but does not actually write to the register.
+ */
+static inline void bcm281xx_pin_update(u32 *reg_val, u32 *reg_mask,
+ u32 param_val, u32 param_shift,
+ u32 param_mask)
+{
+ *reg_val &= ~param_mask;
+ *reg_val |= (param_val << param_shift) & param_mask;
+ *reg_mask |= param_mask;
+}
+
+static struct regmap_config bcm281xx_pinctrl_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = BCM281XX_PIN_VC_CAM3_SDA,
+};
+
+static int bcm281xx_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ return pdata->npins;
+}
+
+static const char *bcm281xx_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned group)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ return pdata->pins[group].name;
+}
+
+static int bcm281xx_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned group,
+ const unsigned **pins,
+ unsigned *num_pins)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ *pins = &pdata->pins[group].number;
+ *num_pins = 1;
+
+ return 0;
+}
+
+static void bcm281xx_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s,
+ unsigned offset)
+{
+ seq_printf(s, " %s", dev_name(pctldev->dev));
+}
+
+static struct pinctrl_ops bcm281xx_pinctrl_ops = {
+ .get_groups_count = bcm281xx_pinctrl_get_groups_count,
+ .get_group_name = bcm281xx_pinctrl_get_group_name,
+ .get_group_pins = bcm281xx_pinctrl_get_group_pins,
+ .pin_dbg_show = bcm281xx_pinctrl_pin_dbg_show,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+ .dt_free_map = pinctrl_utils_dt_free_map,
+};
+
+static int bcm281xx_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ return pdata->nfunctions;
+}
+
+static const char *bcm281xx_pinctrl_get_fcn_name(struct pinctrl_dev *pctldev,
+ unsigned function)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ return pdata->functions[function].name;
+}
+
+static int bcm281xx_pinctrl_get_fcn_groups(struct pinctrl_dev *pctldev,
+ unsigned function,
+ const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ *groups = pdata->functions[function].groups;
+ *num_groups = pdata->functions[function].ngroups;
+
+ return 0;
+}
+
+static int bcm281xx_pinmux_enable(struct pinctrl_dev *pctldev,
+ unsigned function,
+ unsigned group)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+ const struct bcm281xx_pin_function *f = &pdata->functions[function];
+ u32 offset = 4 * pdata->pins[group].number;
+ int rc = 0;
+
+ dev_dbg(pctldev->dev,
+ "%s(): Enable function %s (%d) of pin %s (%d) @offset 0x%x.\n",
+ __func__, f->name, function, pdata->pins[group].name,
+ pdata->pins[group].number, offset);
+
+ rc = regmap_update_bits(pdata->regmap, offset,
+ BCM281XX_PIN_REG_F_SEL_MASK,
+ function << BCM281XX_PIN_REG_F_SEL_SHIFT);
+ if (rc)
+ dev_err(pctldev->dev,
+ "Error updating register for pin %s (%d).\n",
+ pdata->pins[group].name, pdata->pins[group].number);
+
+ return rc;
+}
+
+static struct pinmux_ops bcm281xx_pinctrl_pinmux_ops = {
+ .get_functions_count = bcm281xx_pinctrl_get_fcns_count,
+ .get_function_name = bcm281xx_pinctrl_get_fcn_name,
+ .get_function_groups = bcm281xx_pinctrl_get_fcn_groups,
+ .enable = bcm281xx_pinmux_enable,
+};
+
+static int bcm281xx_pinctrl_pin_config_get(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *config)
+{
+ return -ENOTSUPP;
+}
+
+
+/* Goes through the configs and update register val/mask */
+static int bcm281xx_std_pin_update(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *configs,
+ unsigned num_configs,
+ u32 *val,
+ u32 *mask)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+ int i;
+ enum pin_config_param param;
+ u16 arg;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ arg = (arg >= 1 ? 1 : 0);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(STD, HYST),
+ BCM281XX_PIN_MASK(STD, HYST));
+ break;
+ /*
+ * The pin bias can only be one of pull-up, pull-down, or
+ * disable. The user does not need to specify a value for the
+ * property, and the default value from pinconf-generic is
+ * ignored.
+ */
+ case PIN_CONFIG_BIAS_DISABLE:
+ bcm281xx_pin_update(val, mask, 0,
+ BCM281XX_PIN_SHIFT(STD, PULL_UP),
+ BCM281XX_PIN_MASK(STD, PULL_UP));
+ bcm281xx_pin_update(val, mask, 0,
+ BCM281XX_PIN_SHIFT(STD, PULL_DN),
+ BCM281XX_PIN_MASK(STD, PULL_DN));
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_UP:
+ bcm281xx_pin_update(val, mask, 1,
+ BCM281XX_PIN_SHIFT(STD, PULL_UP),
+ BCM281XX_PIN_MASK(STD, PULL_UP));
+ bcm281xx_pin_update(val, mask, 0,
+ BCM281XX_PIN_SHIFT(STD, PULL_DN),
+ BCM281XX_PIN_MASK(STD, PULL_DN));
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ bcm281xx_pin_update(val, mask, 0,
+ BCM281XX_PIN_SHIFT(STD, PULL_UP),
+ BCM281XX_PIN_MASK(STD, PULL_UP));
+ bcm281xx_pin_update(val, mask, 1,
+ BCM281XX_PIN_SHIFT(STD, PULL_DN),
+ BCM281XX_PIN_MASK(STD, PULL_DN));
+ break;
+
+ case PIN_CONFIG_SLEW_RATE:
+ arg = (arg >= 1 ? 1 : 0);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(STD, SLEW),
+ BCM281XX_PIN_MASK(STD, SLEW));
+ break;
+
+ case PIN_CONFIG_INPUT_ENABLE:
+ /* inversed since register is for input _disable_ */
+ arg = (arg >= 1 ? 0 : 1);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(STD, INPUT_DIS),
+ BCM281XX_PIN_MASK(STD, INPUT_DIS));
+ break;
+
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ /* Valid range is 2-16 mA, even numbers only */
+ if ((arg < 2) || (arg > 16) || (arg % 2)) {
+ dev_err(pctldev->dev,
+ "Invalid Drive Strength value (%d) for "
+ "pin %s (%d). Valid values are "
+ "(2..16) mA, even numbers only.\n",
+ arg, pdata->pins[pin].name, pin);
+ return -EINVAL;
+ }
+ bcm281xx_pin_update(val, mask, (arg/2)-1,
+ BCM281XX_PIN_SHIFT(STD, DRV_STR),
+ BCM281XX_PIN_MASK(STD, DRV_STR));
+ break;
+
+ default:
+ dev_err(pctldev->dev,
+ "Unrecognized pin config %d for pin %s (%d).\n",
+ param, pdata->pins[pin].name, pin);
+ return -EINVAL;
+
+ } /* switch config */
+ } /* for each config */
+
+ return 0;
+}
+
+/*
+ * The pull-up strength for an I2C pin is represented by bits 4-6 in the
+ * register with the following mapping:
+ * 0b000: No pull-up
+ * 0b001: 1200 Ohm
+ * 0b010: 1800 Ohm
+ * 0b011: 720 Ohm
+ * 0b100: 2700 Ohm
+ * 0b101: 831 Ohm
+ * 0b110: 1080 Ohm
+ * 0b111: 568 Ohm
+ * This array maps pull-up strength in Ohms to register values (1+index).
+ */
+static const u16 bcm281xx_pullup_map[] = {
+ 1200, 1800, 720, 2700, 831, 1080, 568
+};
+
+/* Goes through the configs and update register val/mask */
+static int bcm281xx_i2c_pin_update(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *configs,
+ unsigned num_configs,
+ u32 *val,
+ u32 *mask)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+ int i, j;
+ enum pin_config_param param;
+ u16 arg;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_UP:
+ for (j = 0; j < ARRAY_SIZE(bcm281xx_pullup_map); j++)
+ if (bcm281xx_pullup_map[j] == arg)
+ break;
+
+ if (j == ARRAY_SIZE(bcm281xx_pullup_map)) {
+ dev_err(pctldev->dev,
+ "Invalid pull-up value (%d) for pin %s "
+ "(%d). Valid values are 568, 720, 831, "
+ "1080, 1200, 1800, 2700 Ohms.\n",
+ arg, pdata->pins[pin].name, pin);
+ return -EINVAL;
+ }
+
+ bcm281xx_pin_update(val, mask, j+1,
+ BCM281XX_PIN_SHIFT(I2C, PULL_UP_STR),
+ BCM281XX_PIN_MASK(I2C, PULL_UP_STR));
+ break;
+
+ case PIN_CONFIG_BIAS_DISABLE:
+ bcm281xx_pin_update(val, mask, 0,
+ BCM281XX_PIN_SHIFT(I2C, PULL_UP_STR),
+ BCM281XX_PIN_MASK(I2C, PULL_UP_STR));
+ break;
+
+ case PIN_CONFIG_SLEW_RATE:
+ arg = (arg >= 1 ? 1 : 0);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(I2C, SLEW),
+ BCM281XX_PIN_MASK(I2C, SLEW));
+ break;
+
+ case PIN_CONFIG_INPUT_ENABLE:
+ /* inversed since register is for input _disable_ */
+ arg = (arg >= 1 ? 0 : 1);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(I2C, INPUT_DIS),
+ BCM281XX_PIN_MASK(I2C, INPUT_DIS));
+ break;
+
+ default:
+ dev_err(pctldev->dev,
+ "Unrecognized pin config %d for pin %s (%d).\n",
+ param, pdata->pins[pin].name, pin);
+ return -EINVAL;
+
+ } /* switch config */
+ } /* for each config */
+
+ return 0;
+}
+
+/* Goes through the configs and update register val/mask */
+static int bcm281xx_hdmi_pin_update(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *configs,
+ unsigned num_configs,
+ u32 *val,
+ u32 *mask)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+ int i;
+ enum pin_config_param param;
+ u16 arg;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_SLEW_RATE:
+ arg = (arg >= 1 ? 1 : 0);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(HDMI, MODE),
+ BCM281XX_PIN_MASK(HDMI, MODE));
+ break;
+
+ case PIN_CONFIG_INPUT_ENABLE:
+ /* inversed since register is for input _disable_ */
+ arg = (arg >= 1 ? 0 : 1);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(HDMI, INPUT_DIS),
+ BCM281XX_PIN_MASK(HDMI, INPUT_DIS));
+ break;
+
+ default:
+ dev_err(pctldev->dev,
+ "Unrecognized pin config %d for pin %s (%d).\n",
+ param, pdata->pins[pin].name, pin);
+ return -EINVAL;
+
+ } /* switch config */
+ } /* for each config */
+
+ return 0;
+}
+
+static int bcm281xx_pinctrl_pin_config_set(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *configs,
+ unsigned num_configs)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+ enum bcm281xx_pin_type pin_type;
+ u32 offset = 4 * pin;
+ u32 cfg_val, cfg_mask;
+ int rc;
+
+ cfg_val = 0;
+ cfg_mask = 0;
+ pin_type = pin_type_get(pctldev, pin);
+
+ /* Different pins have different configuration options */
+ switch (pin_type) {
+ case BCM281XX_PIN_TYPE_STD:
+ rc = bcm281xx_std_pin_update(pctldev, pin, configs,
+ num_configs, &cfg_val, &cfg_mask);
+ break;
+
+ case BCM281XX_PIN_TYPE_I2C:
+ rc = bcm281xx_i2c_pin_update(pctldev, pin, configs,
+ num_configs, &cfg_val, &cfg_mask);
+ break;
+
+ case BCM281XX_PIN_TYPE_HDMI:
+ rc = bcm281xx_hdmi_pin_update(pctldev, pin, configs,
+ num_configs, &cfg_val, &cfg_mask);
+ break;
+
+ default:
+ dev_err(pctldev->dev, "Unknown pin type for pin %s (%d).\n",
+ pdata->pins[pin].name, pin);
+ return -EINVAL;
+
+ } /* switch pin type */
+
+ if (rc)
+ return rc;
+
+ dev_dbg(pctldev->dev,
+ "%s(): Set pin %s (%d) with config 0x%x, mask 0x%x\n",
+ __func__, pdata->pins[pin].name, pin, cfg_val, cfg_mask);
+
+ rc = regmap_update_bits(pdata->regmap, offset, cfg_mask, cfg_val);
+ if (rc) {
+ dev_err(pctldev->dev,
+ "Error updating register for pin %s (%d).\n",
+ pdata->pins[pin].name, pin);
+ return rc;
+ }
+
+ return 0;
+}
+
+static struct pinconf_ops bcm281xx_pinctrl_pinconf_ops = {
+ .pin_config_get = bcm281xx_pinctrl_pin_config_get,
+ .pin_config_set = bcm281xx_pinctrl_pin_config_set,
+};
+
+static struct pinctrl_desc bcm281xx_pinctrl_desc = {
+ /* name, pins, npins members initialized in probe function */
+ .pctlops = &bcm281xx_pinctrl_ops,
+ .pmxops = &bcm281xx_pinctrl_pinmux_ops,
+ .confops = &bcm281xx_pinctrl_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
+{
+ struct bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl;
+ struct resource *res;
+ struct pinctrl_dev *pctl;
+
+ /* So far We can assume there is only 1 bank of registers */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Missing MEM resource\n");
+ return -ENODEV;
+ }
+
+ pdata->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pdata->reg_base)) {
+ dev_err(&pdev->dev, "Failed to ioremap MEM resource\n");
+ return -ENODEV;
+ }
+
+ /* Initialize the dynamic part of pinctrl_desc */
+ pdata->regmap = devm_regmap_init_mmio(&pdev->dev, pdata->reg_base,
+ &bcm281xx_pinctrl_regmap_config);
+ if (IS_ERR(pdata->regmap)) {
+ dev_err(&pdev->dev, "Regmap MMIO init failed.\n");
+ return -ENODEV;
+ }
+
+ bcm281xx_pinctrl_desc.name = dev_name(&pdev->dev);
+ bcm281xx_pinctrl_desc.pins = bcm281xx_pinctrl.pins;
+ bcm281xx_pinctrl_desc.npins = bcm281xx_pinctrl.npins;
+
+ pctl = pinctrl_register(&bcm281xx_pinctrl_desc,
+ &pdev->dev,
+ pdata);
+ if (!pctl) {
+ dev_err(&pdev->dev, "Failed to register pinctrl\n");
+ return -ENODEV;
+ }
+
+ platform_set_drvdata(pdev, pdata);
+
+ return 0;
+}
+
+static struct of_device_id bcm281xx_pinctrl_of_match[] = {
+ { .compatible = "brcm,bcm11351-pinctrl", },
+ { },
+};
+
+static struct platform_driver bcm281xx_pinctrl_driver = {
+ .driver = {
+ .name = "bcm281xx-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = bcm281xx_pinctrl_of_match,
+ },
+};
+
+module_platform_driver_probe(bcm281xx_pinctrl_driver, bcm281xx_pinctrl_probe);
+
+MODULE_AUTHOR("Broadcom Corporation <bcm-kernel-feedback-list@broadcom.com>");
+MODULE_AUTHOR("Sherman Yin <syin@broadcom.com>");
+MODULE_DESCRIPTION("Broadcom BCM281xx pinctrl driver");
+MODULE_LICENSE("GPL v2");
+++ /dev/null
-/*
- * Copyright (C) 2013 Broadcom Corporation
- *
- * 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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/pinmux.h>
-#include <linux/pinctrl/pinconf.h>
-#include <linux/pinctrl/pinconf-generic.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-#include "core.h"
-#include "pinctrl-utils.h"
-
-/* Capri Pin Control Registers Definitions */
-
-/* Function Select bits are the same for all pin control registers */
-#define CAPRI_PIN_REG_F_SEL_MASK 0x0700
-#define CAPRI_PIN_REG_F_SEL_SHIFT 8
-
-/* Standard pin register */
-#define CAPRI_STD_PIN_REG_DRV_STR_MASK 0x0007
-#define CAPRI_STD_PIN_REG_DRV_STR_SHIFT 0
-#define CAPRI_STD_PIN_REG_INPUT_DIS_MASK 0x0008
-#define CAPRI_STD_PIN_REG_INPUT_DIS_SHIFT 3
-#define CAPRI_STD_PIN_REG_SLEW_MASK 0x0010
-#define CAPRI_STD_PIN_REG_SLEW_SHIFT 4
-#define CAPRI_STD_PIN_REG_PULL_UP_MASK 0x0020
-#define CAPRI_STD_PIN_REG_PULL_UP_SHIFT 5
-#define CAPRI_STD_PIN_REG_PULL_DN_MASK 0x0040
-#define CAPRI_STD_PIN_REG_PULL_DN_SHIFT 6
-#define CAPRI_STD_PIN_REG_HYST_MASK 0x0080
-#define CAPRI_STD_PIN_REG_HYST_SHIFT 7
-
-/* I2C pin register */
-#define CAPRI_I2C_PIN_REG_INPUT_DIS_MASK 0x0004
-#define CAPRI_I2C_PIN_REG_INPUT_DIS_SHIFT 2
-#define CAPRI_I2C_PIN_REG_SLEW_MASK 0x0008
-#define CAPRI_I2C_PIN_REG_SLEW_SHIFT 3
-#define CAPRI_I2C_PIN_REG_PULL_UP_STR_MASK 0x0070
-#define CAPRI_I2C_PIN_REG_PULL_UP_STR_SHIFT 4
-
-/* HDMI pin register */
-#define CAPRI_HDMI_PIN_REG_INPUT_DIS_MASK 0x0008
-#define CAPRI_HDMI_PIN_REG_INPUT_DIS_SHIFT 3
-#define CAPRI_HDMI_PIN_REG_MODE_MASK 0x0010
-#define CAPRI_HDMI_PIN_REG_MODE_SHIFT 4
-
-/**
- * capri_pin_type - types of pin register
- */
-enum capri_pin_type {
- CAPRI_PIN_TYPE_UNKNOWN = 0,
- CAPRI_PIN_TYPE_STD,
- CAPRI_PIN_TYPE_I2C,
- CAPRI_PIN_TYPE_HDMI,
-};
-
-static enum capri_pin_type std_pin = CAPRI_PIN_TYPE_STD;
-static enum capri_pin_type i2c_pin = CAPRI_PIN_TYPE_I2C;
-static enum capri_pin_type hdmi_pin = CAPRI_PIN_TYPE_HDMI;
-
-/**
- * capri_pin_function- define pin function
- */
-struct capri_pin_function {
- const char *name;
- const char * const *groups;
- const unsigned ngroups;
-};
-
-/**
- * capri_pinctrl_data - Broadcom-specific pinctrl data
- * @reg_base - base of pinctrl registers
- */
-struct capri_pinctrl_data {
- void __iomem *reg_base;
-
- /* List of all pins */
- const struct pinctrl_pin_desc *pins;
- const unsigned npins;
-
- const struct capri_pin_function *functions;
- const unsigned nfunctions;
-
- struct regmap *regmap;
-};
-
-/*
- * Pin number definition. The order here must be the same as defined in the
- * PADCTRLREG block in the RDB.
- */
-#define CAPRI_PIN_ADCSYNC 0
-#define CAPRI_PIN_BAT_RM 1
-#define CAPRI_PIN_BSC1_SCL 2
-#define CAPRI_PIN_BSC1_SDA 3
-#define CAPRI_PIN_BSC2_SCL 4
-#define CAPRI_PIN_BSC2_SDA 5
-#define CAPRI_PIN_CLASSGPWR 6
-#define CAPRI_PIN_CLK_CX8 7
-#define CAPRI_PIN_CLKOUT_0 8
-#define CAPRI_PIN_CLKOUT_1 9
-#define CAPRI_PIN_CLKOUT_2 10
-#define CAPRI_PIN_CLKOUT_3 11
-#define CAPRI_PIN_CLKREQ_IN_0 12
-#define CAPRI_PIN_CLKREQ_IN_1 13
-#define CAPRI_PIN_CWS_SYS_REQ1 14
-#define CAPRI_PIN_CWS_SYS_REQ2 15
-#define CAPRI_PIN_CWS_SYS_REQ3 16
-#define CAPRI_PIN_DIGMIC1_CLK 17
-#define CAPRI_PIN_DIGMIC1_DQ 18
-#define CAPRI_PIN_DIGMIC2_CLK 19
-#define CAPRI_PIN_DIGMIC2_DQ 20
-#define CAPRI_PIN_GPEN13 21
-#define CAPRI_PIN_GPEN14 22
-#define CAPRI_PIN_GPEN15 23
-#define CAPRI_PIN_GPIO00 24
-#define CAPRI_PIN_GPIO01 25
-#define CAPRI_PIN_GPIO02 26
-#define CAPRI_PIN_GPIO03 27
-#define CAPRI_PIN_GPIO04 28
-#define CAPRI_PIN_GPIO05 29
-#define CAPRI_PIN_GPIO06 30
-#define CAPRI_PIN_GPIO07 31
-#define CAPRI_PIN_GPIO08 32
-#define CAPRI_PIN_GPIO09 33
-#define CAPRI_PIN_GPIO10 34
-#define CAPRI_PIN_GPIO11 35
-#define CAPRI_PIN_GPIO12 36
-#define CAPRI_PIN_GPIO13 37
-#define CAPRI_PIN_GPIO14 38
-#define CAPRI_PIN_GPS_PABLANK 39
-#define CAPRI_PIN_GPS_TMARK 40
-#define CAPRI_PIN_HDMI_SCL 41
-#define CAPRI_PIN_HDMI_SDA 42
-#define CAPRI_PIN_IC_DM 43
-#define CAPRI_PIN_IC_DP 44
-#define CAPRI_PIN_KP_COL_IP_0 45
-#define CAPRI_PIN_KP_COL_IP_1 46
-#define CAPRI_PIN_KP_COL_IP_2 47
-#define CAPRI_PIN_KP_COL_IP_3 48
-#define CAPRI_PIN_KP_ROW_OP_0 49
-#define CAPRI_PIN_KP_ROW_OP_1 50
-#define CAPRI_PIN_KP_ROW_OP_2 51
-#define CAPRI_PIN_KP_ROW_OP_3 52
-#define CAPRI_PIN_LCD_B_0 53
-#define CAPRI_PIN_LCD_B_1 54
-#define CAPRI_PIN_LCD_B_2 55
-#define CAPRI_PIN_LCD_B_3 56
-#define CAPRI_PIN_LCD_B_4 57
-#define CAPRI_PIN_LCD_B_5 58
-#define CAPRI_PIN_LCD_B_6 59
-#define CAPRI_PIN_LCD_B_7 60
-#define CAPRI_PIN_LCD_G_0 61
-#define CAPRI_PIN_LCD_G_1 62
-#define CAPRI_PIN_LCD_G_2 63
-#define CAPRI_PIN_LCD_G_3 64
-#define CAPRI_PIN_LCD_G_4 65
-#define CAPRI_PIN_LCD_G_5 66
-#define CAPRI_PIN_LCD_G_6 67
-#define CAPRI_PIN_LCD_G_7 68
-#define CAPRI_PIN_LCD_HSYNC 69
-#define CAPRI_PIN_LCD_OE 70
-#define CAPRI_PIN_LCD_PCLK 71
-#define CAPRI_PIN_LCD_R_0 72
-#define CAPRI_PIN_LCD_R_1 73
-#define CAPRI_PIN_LCD_R_2 74
-#define CAPRI_PIN_LCD_R_3 75
-#define CAPRI_PIN_LCD_R_4 76
-#define CAPRI_PIN_LCD_R_5 77
-#define CAPRI_PIN_LCD_R_6 78
-#define CAPRI_PIN_LCD_R_7 79
-#define CAPRI_PIN_LCD_VSYNC 80
-#define CAPRI_PIN_MDMGPIO0 81
-#define CAPRI_PIN_MDMGPIO1 82
-#define CAPRI_PIN_MDMGPIO2 83
-#define CAPRI_PIN_MDMGPIO3 84
-#define CAPRI_PIN_MDMGPIO4 85
-#define CAPRI_PIN_MDMGPIO5 86
-#define CAPRI_PIN_MDMGPIO6 87
-#define CAPRI_PIN_MDMGPIO7 88
-#define CAPRI_PIN_MDMGPIO8 89
-#define CAPRI_PIN_MPHI_DATA_0 90
-#define CAPRI_PIN_MPHI_DATA_1 91
-#define CAPRI_PIN_MPHI_DATA_2 92
-#define CAPRI_PIN_MPHI_DATA_3 93
-#define CAPRI_PIN_MPHI_DATA_4 94
-#define CAPRI_PIN_MPHI_DATA_5 95
-#define CAPRI_PIN_MPHI_DATA_6 96
-#define CAPRI_PIN_MPHI_DATA_7 97
-#define CAPRI_PIN_MPHI_DATA_8 98
-#define CAPRI_PIN_MPHI_DATA_9 99
-#define CAPRI_PIN_MPHI_DATA_10 100
-#define CAPRI_PIN_MPHI_DATA_11 101
-#define CAPRI_PIN_MPHI_DATA_12 102
-#define CAPRI_PIN_MPHI_DATA_13 103
-#define CAPRI_PIN_MPHI_DATA_14 104
-#define CAPRI_PIN_MPHI_DATA_15 105
-#define CAPRI_PIN_MPHI_HA0 106
-#define CAPRI_PIN_MPHI_HAT0 107
-#define CAPRI_PIN_MPHI_HAT1 108
-#define CAPRI_PIN_MPHI_HCE0_N 109
-#define CAPRI_PIN_MPHI_HCE1_N 110
-#define CAPRI_PIN_MPHI_HRD_N 111
-#define CAPRI_PIN_MPHI_HWR_N 112
-#define CAPRI_PIN_MPHI_RUN0 113
-#define CAPRI_PIN_MPHI_RUN1 114
-#define CAPRI_PIN_MTX_SCAN_CLK 115
-#define CAPRI_PIN_MTX_SCAN_DATA 116
-#define CAPRI_PIN_NAND_AD_0 117
-#define CAPRI_PIN_NAND_AD_1 118
-#define CAPRI_PIN_NAND_AD_2 119
-#define CAPRI_PIN_NAND_AD_3 120
-#define CAPRI_PIN_NAND_AD_4 121
-#define CAPRI_PIN_NAND_AD_5 122
-#define CAPRI_PIN_NAND_AD_6 123
-#define CAPRI_PIN_NAND_AD_7 124
-#define CAPRI_PIN_NAND_ALE 125
-#define CAPRI_PIN_NAND_CEN_0 126
-#define CAPRI_PIN_NAND_CEN_1 127
-#define CAPRI_PIN_NAND_CLE 128
-#define CAPRI_PIN_NAND_OEN 129
-#define CAPRI_PIN_NAND_RDY_0 130
-#define CAPRI_PIN_NAND_RDY_1 131
-#define CAPRI_PIN_NAND_WEN 132
-#define CAPRI_PIN_NAND_WP 133
-#define CAPRI_PIN_PC1 134
-#define CAPRI_PIN_PC2 135
-#define CAPRI_PIN_PMU_INT 136
-#define CAPRI_PIN_PMU_SCL 137
-#define CAPRI_PIN_PMU_SDA 138
-#define CAPRI_PIN_RFST2G_MTSLOTEN3G 139
-#define CAPRI_PIN_RGMII_0_RX_CTL 140
-#define CAPRI_PIN_RGMII_0_RXC 141
-#define CAPRI_PIN_RGMII_0_RXD_0 142
-#define CAPRI_PIN_RGMII_0_RXD_1 143
-#define CAPRI_PIN_RGMII_0_RXD_2 144
-#define CAPRI_PIN_RGMII_0_RXD_3 145
-#define CAPRI_PIN_RGMII_0_TX_CTL 146
-#define CAPRI_PIN_RGMII_0_TXC 147
-#define CAPRI_PIN_RGMII_0_TXD_0 148
-#define CAPRI_PIN_RGMII_0_TXD_1 149
-#define CAPRI_PIN_RGMII_0_TXD_2 150
-#define CAPRI_PIN_RGMII_0_TXD_3 151
-#define CAPRI_PIN_RGMII_1_RX_CTL 152
-#define CAPRI_PIN_RGMII_1_RXC 153
-#define CAPRI_PIN_RGMII_1_RXD_0 154
-#define CAPRI_PIN_RGMII_1_RXD_1 155
-#define CAPRI_PIN_RGMII_1_RXD_2 156
-#define CAPRI_PIN_RGMII_1_RXD_3 157
-#define CAPRI_PIN_RGMII_1_TX_CTL 158
-#define CAPRI_PIN_RGMII_1_TXC 159
-#define CAPRI_PIN_RGMII_1_TXD_0 160
-#define CAPRI_PIN_RGMII_1_TXD_1 161
-#define CAPRI_PIN_RGMII_1_TXD_2 162
-#define CAPRI_PIN_RGMII_1_TXD_3 163
-#define CAPRI_PIN_RGMII_GPIO_0 164
-#define CAPRI_PIN_RGMII_GPIO_1 165
-#define CAPRI_PIN_RGMII_GPIO_2 166
-#define CAPRI_PIN_RGMII_GPIO_3 167
-#define CAPRI_PIN_RTXDATA2G_TXDATA3G1 168
-#define CAPRI_PIN_RTXEN2G_TXDATA3G2 169
-#define CAPRI_PIN_RXDATA3G0 170
-#define CAPRI_PIN_RXDATA3G1 171
-#define CAPRI_PIN_RXDATA3G2 172
-#define CAPRI_PIN_SDIO1_CLK 173
-#define CAPRI_PIN_SDIO1_CMD 174
-#define CAPRI_PIN_SDIO1_DATA_0 175
-#define CAPRI_PIN_SDIO1_DATA_1 176
-#define CAPRI_PIN_SDIO1_DATA_2 177
-#define CAPRI_PIN_SDIO1_DATA_3 178
-#define CAPRI_PIN_SDIO4_CLK 179
-#define CAPRI_PIN_SDIO4_CMD 180
-#define CAPRI_PIN_SDIO4_DATA_0 181
-#define CAPRI_PIN_SDIO4_DATA_1 182
-#define CAPRI_PIN_SDIO4_DATA_2 183
-#define CAPRI_PIN_SDIO4_DATA_3 184
-#define CAPRI_PIN_SIM_CLK 185
-#define CAPRI_PIN_SIM_DATA 186
-#define CAPRI_PIN_SIM_DET 187
-#define CAPRI_PIN_SIM_RESETN 188
-#define CAPRI_PIN_SIM2_CLK 189
-#define CAPRI_PIN_SIM2_DATA 190
-#define CAPRI_PIN_SIM2_DET 191
-#define CAPRI_PIN_SIM2_RESETN 192
-#define CAPRI_PIN_SRI_C 193
-#define CAPRI_PIN_SRI_D 194
-#define CAPRI_PIN_SRI_E 195
-#define CAPRI_PIN_SSP_EXTCLK 196
-#define CAPRI_PIN_SSP0_CLK 197
-#define CAPRI_PIN_SSP0_FS 198
-#define CAPRI_PIN_SSP0_RXD 199
-#define CAPRI_PIN_SSP0_TXD 200
-#define CAPRI_PIN_SSP2_CLK 201
-#define CAPRI_PIN_SSP2_FS_0 202
-#define CAPRI_PIN_SSP2_FS_1 203
-#define CAPRI_PIN_SSP2_FS_2 204
-#define CAPRI_PIN_SSP2_FS_3 205
-#define CAPRI_PIN_SSP2_RXD_0 206
-#define CAPRI_PIN_SSP2_RXD_1 207
-#define CAPRI_PIN_SSP2_TXD_0 208
-#define CAPRI_PIN_SSP2_TXD_1 209
-#define CAPRI_PIN_SSP3_CLK 210
-#define CAPRI_PIN_SSP3_FS 211
-#define CAPRI_PIN_SSP3_RXD 212
-#define CAPRI_PIN_SSP3_TXD 213
-#define CAPRI_PIN_SSP4_CLK 214
-#define CAPRI_PIN_SSP4_FS 215
-#define CAPRI_PIN_SSP4_RXD 216
-#define CAPRI_PIN_SSP4_TXD 217
-#define CAPRI_PIN_SSP5_CLK 218
-#define CAPRI_PIN_SSP5_FS 219
-#define CAPRI_PIN_SSP5_RXD 220
-#define CAPRI_PIN_SSP5_TXD 221
-#define CAPRI_PIN_SSP6_CLK 222
-#define CAPRI_PIN_SSP6_FS 223
-#define CAPRI_PIN_SSP6_RXD 224
-#define CAPRI_PIN_SSP6_TXD 225
-#define CAPRI_PIN_STAT_1 226
-#define CAPRI_PIN_STAT_2 227
-#define CAPRI_PIN_SYSCLKEN 228
-#define CAPRI_PIN_TRACECLK 229
-#define CAPRI_PIN_TRACEDT00 230
-#define CAPRI_PIN_TRACEDT01 231
-#define CAPRI_PIN_TRACEDT02 232
-#define CAPRI_PIN_TRACEDT03 233
-#define CAPRI_PIN_TRACEDT04 234
-#define CAPRI_PIN_TRACEDT05 235
-#define CAPRI_PIN_TRACEDT06 236
-#define CAPRI_PIN_TRACEDT07 237
-#define CAPRI_PIN_TRACEDT08 238
-#define CAPRI_PIN_TRACEDT09 239
-#define CAPRI_PIN_TRACEDT10 240
-#define CAPRI_PIN_TRACEDT11 241
-#define CAPRI_PIN_TRACEDT12 242
-#define CAPRI_PIN_TRACEDT13 243
-#define CAPRI_PIN_TRACEDT14 244
-#define CAPRI_PIN_TRACEDT15 245
-#define CAPRI_PIN_TXDATA3G0 246
-#define CAPRI_PIN_TXPWRIND 247
-#define CAPRI_PIN_UARTB1_UCTS 248
-#define CAPRI_PIN_UARTB1_URTS 249
-#define CAPRI_PIN_UARTB1_URXD 250
-#define CAPRI_PIN_UARTB1_UTXD 251
-#define CAPRI_PIN_UARTB2_URXD 252
-#define CAPRI_PIN_UARTB2_UTXD 253
-#define CAPRI_PIN_UARTB3_UCTS 254
-#define CAPRI_PIN_UARTB3_URTS 255
-#define CAPRI_PIN_UARTB3_URXD 256
-#define CAPRI_PIN_UARTB3_UTXD 257
-#define CAPRI_PIN_UARTB4_UCTS 258
-#define CAPRI_PIN_UARTB4_URTS 259
-#define CAPRI_PIN_UARTB4_URXD 260
-#define CAPRI_PIN_UARTB4_UTXD 261
-#define CAPRI_PIN_VC_CAM1_SCL 262
-#define CAPRI_PIN_VC_CAM1_SDA 263
-#define CAPRI_PIN_VC_CAM2_SCL 264
-#define CAPRI_PIN_VC_CAM2_SDA 265
-#define CAPRI_PIN_VC_CAM3_SCL 266
-#define CAPRI_PIN_VC_CAM3_SDA 267
-
-#define CAPRI_PIN_DESC(a, b, c) \
- { .number = a, .name = b, .drv_data = &c##_pin }
-
-/*
- * Pin description definition. The order here must be the same as defined in
- * the PADCTRLREG block in the RDB, since the pin number is used as an index
- * into this array.
- */
-static const struct pinctrl_pin_desc capri_pinctrl_pins[] = {
- CAPRI_PIN_DESC(CAPRI_PIN_ADCSYNC, "adcsync", std),
- CAPRI_PIN_DESC(CAPRI_PIN_BAT_RM, "bat_rm", std),
- CAPRI_PIN_DESC(CAPRI_PIN_BSC1_SCL, "bsc1_scl", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_BSC1_SDA, "bsc1_sda", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_BSC2_SCL, "bsc2_scl", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_BSC2_SDA, "bsc2_sda", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_CLASSGPWR, "classgpwr", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLK_CX8, "clk_cx8", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_0, "clkout_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_1, "clkout_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_2, "clkout_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_3, "clkout_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLKREQ_IN_0, "clkreq_in_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLKREQ_IN_1, "clkreq_in_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CWS_SYS_REQ1, "cws_sys_req1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CWS_SYS_REQ2, "cws_sys_req2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CWS_SYS_REQ3, "cws_sys_req3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC1_CLK, "digmic1_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC1_DQ, "digmic1_dq", std),
- CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC2_CLK, "digmic2_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC2_DQ, "digmic2_dq", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPEN13, "gpen13", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPEN14, "gpen14", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPEN15, "gpen15", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO00, "gpio00", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO01, "gpio01", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO02, "gpio02", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO03, "gpio03", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO04, "gpio04", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO05, "gpio05", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO06, "gpio06", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO07, "gpio07", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO08, "gpio08", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO09, "gpio09", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO10, "gpio10", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO11, "gpio11", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO12, "gpio12", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO13, "gpio13", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO14, "gpio14", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPS_PABLANK, "gps_pablank", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPS_TMARK, "gps_tmark", std),
- CAPRI_PIN_DESC(CAPRI_PIN_HDMI_SCL, "hdmi_scl", hdmi),
- CAPRI_PIN_DESC(CAPRI_PIN_HDMI_SDA, "hdmi_sda", hdmi),
- CAPRI_PIN_DESC(CAPRI_PIN_IC_DM, "ic_dm", std),
- CAPRI_PIN_DESC(CAPRI_PIN_IC_DP, "ic_dp", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_0, "kp_col_ip_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_1, "kp_col_ip_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_2, "kp_col_ip_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_3, "kp_col_ip_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_0, "kp_row_op_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_1, "kp_row_op_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_2, "kp_row_op_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_3, "kp_row_op_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_0, "lcd_b_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_1, "lcd_b_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_2, "lcd_b_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_3, "lcd_b_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_4, "lcd_b_4", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_5, "lcd_b_5", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_6, "lcd_b_6", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_7, "lcd_b_7", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_0, "lcd_g_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_1, "lcd_g_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_2, "lcd_g_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_3, "lcd_g_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_4, "lcd_g_4", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_5, "lcd_g_5", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_6, "lcd_g_6", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_7, "lcd_g_7", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_HSYNC, "lcd_hsync", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_OE, "lcd_oe", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_PCLK, "lcd_pclk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_0, "lcd_r_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_1, "lcd_r_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_2, "lcd_r_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_3, "lcd_r_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_4, "lcd_r_4", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_5, "lcd_r_5", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_6, "lcd_r_6", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_7, "lcd_r_7", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_VSYNC, "lcd_vsync", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO0, "mdmgpio0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO1, "mdmgpio1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO2, "mdmgpio2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO3, "mdmgpio3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO4, "mdmgpio4", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO5, "mdmgpio5", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO6, "mdmgpio6", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO7, "mdmgpio7", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO8, "mdmgpio8", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_0, "mphi_data_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_1, "mphi_data_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_2, "mphi_data_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_3, "mphi_data_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_4, "mphi_data_4", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_5, "mphi_data_5", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_6, "mphi_data_6", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_7, "mphi_data_7", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_8, "mphi_data_8", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_9, "mphi_data_9", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_10, "mphi_data_10", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_11, "mphi_data_11", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_12, "mphi_data_12", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_13, "mphi_data_13", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_14, "mphi_data_14", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_15, "mphi_data_15", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HA0, "mphi_ha0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HAT0, "mphi_hat0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HAT1, "mphi_hat1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HCE0_N, "mphi_hce0_n", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HCE1_N, "mphi_hce1_n", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HRD_N, "mphi_hrd_n", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HWR_N, "mphi_hwr_n", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_RUN0, "mphi_run0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_RUN1, "mphi_run1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MTX_SCAN_CLK, "mtx_scan_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MTX_SCAN_DATA, "mtx_scan_data", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_0, "nand_ad_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_1, "nand_ad_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_2, "nand_ad_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_3, "nand_ad_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_4, "nand_ad_4", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_5, "nand_ad_5", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_6, "nand_ad_6", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_7, "nand_ad_7", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_ALE, "nand_ale", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_CEN_0, "nand_cen_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_CEN_1, "nand_cen_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_CLE, "nand_cle", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_OEN, "nand_oen", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_RDY_0, "nand_rdy_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_RDY_1, "nand_rdy_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_WEN, "nand_wen", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_WP, "nand_wp", std),
- CAPRI_PIN_DESC(CAPRI_PIN_PC1, "pc1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_PC2, "pc2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_PMU_INT, "pmu_int", std),
- CAPRI_PIN_DESC(CAPRI_PIN_PMU_SCL, "pmu_scl", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_PMU_SDA, "pmu_sda", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_RFST2G_MTSLOTEN3G, "rfst2g_mtsloten3g", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RX_CTL, "rgmii_0_rx_ctl", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXC, "rgmii_0_rxc", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_0, "rgmii_0_rxd_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_1, "rgmii_0_rxd_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_2, "rgmii_0_rxd_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_3, "rgmii_0_rxd_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TX_CTL, "rgmii_0_tx_ctl", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXC, "rgmii_0_txc", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_0, "rgmii_0_txd_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_1, "rgmii_0_txd_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_2, "rgmii_0_txd_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_3, "rgmii_0_txd_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RX_CTL, "rgmii_1_rx_ctl", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXC, "rgmii_1_rxc", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_0, "rgmii_1_rxd_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_1, "rgmii_1_rxd_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_2, "rgmii_1_rxd_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_3, "rgmii_1_rxd_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TX_CTL, "rgmii_1_tx_ctl", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXC, "rgmii_1_txc", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_0, "rgmii_1_txd_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_1, "rgmii_1_txd_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_2, "rgmii_1_txd_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_3, "rgmii_1_txd_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_0, "rgmii_gpio_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_1, "rgmii_gpio_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_2, "rgmii_gpio_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_3, "rgmii_gpio_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RTXDATA2G_TXDATA3G1, "rtxdata2g_txdata3g1",
- std),
- CAPRI_PIN_DESC(CAPRI_PIN_RTXEN2G_TXDATA3G2, "rtxen2g_txdata3g2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RXDATA3G0, "rxdata3g0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RXDATA3G1, "rxdata3g1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RXDATA3G2, "rxdata3g2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_CLK, "sdio1_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_CMD, "sdio1_cmd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_0, "sdio1_data_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_1, "sdio1_data_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_2, "sdio1_data_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_3, "sdio1_data_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_CLK, "sdio4_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_CMD, "sdio4_cmd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_0, "sdio4_data_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_1, "sdio4_data_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_2, "sdio4_data_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_3, "sdio4_data_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM_CLK, "sim_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM_DATA, "sim_data", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM_DET, "sim_det", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM_RESETN, "sim_resetn", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM2_CLK, "sim2_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM2_DATA, "sim2_data", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM2_DET, "sim2_det", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM2_RESETN, "sim2_resetn", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SRI_C, "sri_c", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SRI_D, "sri_d", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SRI_E, "sri_e", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP_EXTCLK, "ssp_extclk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP0_CLK, "ssp0_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP0_FS, "ssp0_fs", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP0_RXD, "ssp0_rxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP0_TXD, "ssp0_txd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_CLK, "ssp2_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_0, "ssp2_fs_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_1, "ssp2_fs_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_2, "ssp2_fs_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_3, "ssp2_fs_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_RXD_0, "ssp2_rxd_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_RXD_1, "ssp2_rxd_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_TXD_0, "ssp2_txd_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_TXD_1, "ssp2_txd_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP3_CLK, "ssp3_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP3_FS, "ssp3_fs", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP3_RXD, "ssp3_rxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP3_TXD, "ssp3_txd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP4_CLK, "ssp4_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP4_FS, "ssp4_fs", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP4_RXD, "ssp4_rxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP4_TXD, "ssp4_txd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP5_CLK, "ssp5_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP5_FS, "ssp5_fs", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP5_RXD, "ssp5_rxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP5_TXD, "ssp5_txd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP6_CLK, "ssp6_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP6_FS, "ssp6_fs", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP6_RXD, "ssp6_rxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP6_TXD, "ssp6_txd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_STAT_1, "stat_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_STAT_2, "stat_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SYSCLKEN, "sysclken", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACECLK, "traceclk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT00, "tracedt00", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT01, "tracedt01", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT02, "tracedt02", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT03, "tracedt03", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT04, "tracedt04", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT05, "tracedt05", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT06, "tracedt06", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT07, "tracedt07", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT08, "tracedt08", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT09, "tracedt09", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT10, "tracedt10", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT11, "tracedt11", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT12, "tracedt12", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT13, "tracedt13", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT14, "tracedt14", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT15, "tracedt15", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TXDATA3G0, "txdata3g0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TXPWRIND, "txpwrind", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_UCTS, "uartb1_ucts", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_URTS, "uartb1_urts", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_URXD, "uartb1_urxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_UTXD, "uartb1_utxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB2_URXD, "uartb2_urxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB2_UTXD, "uartb2_utxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_UCTS, "uartb3_ucts", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_URTS, "uartb3_urts", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_URXD, "uartb3_urxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_UTXD, "uartb3_utxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_UCTS, "uartb4_ucts", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_URTS, "uartb4_urts", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_URXD, "uartb4_urxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_UTXD, "uartb4_utxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM1_SCL, "vc_cam1_scl", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM1_SDA, "vc_cam1_sda", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM2_SCL, "vc_cam2_scl", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM2_SDA, "vc_cam2_sda", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM3_SCL, "vc_cam3_scl", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM3_SDA, "vc_cam3_sda", i2c),
-};
-
-static const char * const capri_alt_groups[] = {
- "adcsync",
- "bat_rm",
- "bsc1_scl",
- "bsc1_sda",
- "bsc2_scl",
- "bsc2_sda",
- "classgpwr",
- "clk_cx8",
- "clkout_0",
- "clkout_1",
- "clkout_2",
- "clkout_3",
- "clkreq_in_0",
- "clkreq_in_1",
- "cws_sys_req1",
- "cws_sys_req2",
- "cws_sys_req3",
- "digmic1_clk",
- "digmic1_dq",
- "digmic2_clk",
- "digmic2_dq",
- "gpen13",
- "gpen14",
- "gpen15",
- "gpio00",
- "gpio01",
- "gpio02",
- "gpio03",
- "gpio04",
- "gpio05",
- "gpio06",
- "gpio07",
- "gpio08",
- "gpio09",
- "gpio10",
- "gpio11",
- "gpio12",
- "gpio13",
- "gpio14",
- "gps_pablank",
- "gps_tmark",
- "hdmi_scl",
- "hdmi_sda",
- "ic_dm",
- "ic_dp",
- "kp_col_ip_0",
- "kp_col_ip_1",
- "kp_col_ip_2",
- "kp_col_ip_3",
- "kp_row_op_0",
- "kp_row_op_1",
- "kp_row_op_2",
- "kp_row_op_3",
- "lcd_b_0",
- "lcd_b_1",
- "lcd_b_2",
- "lcd_b_3",
- "lcd_b_4",
- "lcd_b_5",
- "lcd_b_6",
- "lcd_b_7",
- "lcd_g_0",
- "lcd_g_1",
- "lcd_g_2",
- "lcd_g_3",
- "lcd_g_4",
- "lcd_g_5",
- "lcd_g_6",
- "lcd_g_7",
- "lcd_hsync",
- "lcd_oe",
- "lcd_pclk",
- "lcd_r_0",
- "lcd_r_1",
- "lcd_r_2",
- "lcd_r_3",
- "lcd_r_4",
- "lcd_r_5",
- "lcd_r_6",
- "lcd_r_7",
- "lcd_vsync",
- "mdmgpio0",
- "mdmgpio1",
- "mdmgpio2",
- "mdmgpio3",
- "mdmgpio4",
- "mdmgpio5",
- "mdmgpio6",
- "mdmgpio7",
- "mdmgpio8",
- "mphi_data_0",
- "mphi_data_1",
- "mphi_data_2",
- "mphi_data_3",
- "mphi_data_4",
- "mphi_data_5",
- "mphi_data_6",
- "mphi_data_7",
- "mphi_data_8",
- "mphi_data_9",
- "mphi_data_10",
- "mphi_data_11",
- "mphi_data_12",
- "mphi_data_13",
- "mphi_data_14",
- "mphi_data_15",
- "mphi_ha0",
- "mphi_hat0",
- "mphi_hat1",
- "mphi_hce0_n",
- "mphi_hce1_n",
- "mphi_hrd_n",
- "mphi_hwr_n",
- "mphi_run0",
- "mphi_run1",
- "mtx_scan_clk",
- "mtx_scan_data",
- "nand_ad_0",
- "nand_ad_1",
- "nand_ad_2",
- "nand_ad_3",
- "nand_ad_4",
- "nand_ad_5",
- "nand_ad_6",
- "nand_ad_7",
- "nand_ale",
- "nand_cen_0",
- "nand_cen_1",
- "nand_cle",
- "nand_oen",
- "nand_rdy_0",
- "nand_rdy_1",
- "nand_wen",
- "nand_wp",
- "pc1",
- "pc2",
- "pmu_int",
- "pmu_scl",
- "pmu_sda",
- "rfst2g_mtsloten3g",
- "rgmii_0_rx_ctl",
- "rgmii_0_rxc",
- "rgmii_0_rxd_0",
- "rgmii_0_rxd_1",
- "rgmii_0_rxd_2",
- "rgmii_0_rxd_3",
- "rgmii_0_tx_ctl",
- "rgmii_0_txc",
- "rgmii_0_txd_0",
- "rgmii_0_txd_1",
- "rgmii_0_txd_2",
- "rgmii_0_txd_3",
- "rgmii_1_rx_ctl",
- "rgmii_1_rxc",
- "rgmii_1_rxd_0",
- "rgmii_1_rxd_1",
- "rgmii_1_rxd_2",
- "rgmii_1_rxd_3",
- "rgmii_1_tx_ctl",
- "rgmii_1_txc",
- "rgmii_1_txd_0",
- "rgmii_1_txd_1",
- "rgmii_1_txd_2",
- "rgmii_1_txd_3",
- "rgmii_gpio_0",
- "rgmii_gpio_1",
- "rgmii_gpio_2",
- "rgmii_gpio_3",
- "rtxdata2g_txdata3g1",
- "rtxen2g_txdata3g2",
- "rxdata3g0",
- "rxdata3g1",
- "rxdata3g2",
- "sdio1_clk",
- "sdio1_cmd",
- "sdio1_data_0",
- "sdio1_data_1",
- "sdio1_data_2",
- "sdio1_data_3",
- "sdio4_clk",
- "sdio4_cmd",
- "sdio4_data_0",
- "sdio4_data_1",
- "sdio4_data_2",
- "sdio4_data_3",
- "sim_clk",
- "sim_data",
- "sim_det",
- "sim_resetn",
- "sim2_clk",
- "sim2_data",
- "sim2_det",
- "sim2_resetn",
- "sri_c",
- "sri_d",
- "sri_e",
- "ssp_extclk",
- "ssp0_clk",
- "ssp0_fs",
- "ssp0_rxd",
- "ssp0_txd",
- "ssp2_clk",
- "ssp2_fs_0",
- "ssp2_fs_1",
- "ssp2_fs_2",
- "ssp2_fs_3",
- "ssp2_rxd_0",
- "ssp2_rxd_1",
- "ssp2_txd_0",
- "ssp2_txd_1",
- "ssp3_clk",
- "ssp3_fs",
- "ssp3_rxd",
- "ssp3_txd",
- "ssp4_clk",
- "ssp4_fs",
- "ssp4_rxd",
- "ssp4_txd",
- "ssp5_clk",
- "ssp5_fs",
- "ssp5_rxd",
- "ssp5_txd",
- "ssp6_clk",
- "ssp6_fs",
- "ssp6_rxd",
- "ssp6_txd",
- "stat_1",
- "stat_2",
- "sysclken",
- "traceclk",
- "tracedt00",
- "tracedt01",
- "tracedt02",
- "tracedt03",
- "tracedt04",
- "tracedt05",
- "tracedt06",
- "tracedt07",
- "tracedt08",
- "tracedt09",
- "tracedt10",
- "tracedt11",
- "tracedt12",
- "tracedt13",
- "tracedt14",
- "tracedt15",
- "txdata3g0",
- "txpwrind",
- "uartb1_ucts",
- "uartb1_urts",
- "uartb1_urxd",
- "uartb1_utxd",
- "uartb2_urxd",
- "uartb2_utxd",
- "uartb3_ucts",
- "uartb3_urts",
- "uartb3_urxd",
- "uartb3_utxd",
- "uartb4_ucts",
- "uartb4_urts",
- "uartb4_urxd",
- "uartb4_utxd",
- "vc_cam1_scl",
- "vc_cam1_sda",
- "vc_cam2_scl",
- "vc_cam2_sda",
- "vc_cam3_scl",
- "vc_cam3_sda",
-};
-
-/* Every pin can implement all ALT1-ALT4 functions */
-#define CAPRI_PIN_FUNCTION(fcn_name) \
-{ \
- .name = #fcn_name, \
- .groups = capri_alt_groups, \
- .ngroups = ARRAY_SIZE(capri_alt_groups), \
-}
-
-static const struct capri_pin_function capri_functions[] = {
- CAPRI_PIN_FUNCTION(alt1),
- CAPRI_PIN_FUNCTION(alt2),
- CAPRI_PIN_FUNCTION(alt3),
- CAPRI_PIN_FUNCTION(alt4),
-};
-
-static struct capri_pinctrl_data capri_pinctrl = {
- .pins = capri_pinctrl_pins,
- .npins = ARRAY_SIZE(capri_pinctrl_pins),
- .functions = capri_functions,
- .nfunctions = ARRAY_SIZE(capri_functions),
-};
-
-static inline enum capri_pin_type pin_type_get(struct pinctrl_dev *pctldev,
- unsigned pin)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- if (pin >= pdata->npins)
- return CAPRI_PIN_TYPE_UNKNOWN;
-
- return *(enum capri_pin_type *)(pdata->pins[pin].drv_data);
-}
-
-#define CAPRI_PIN_SHIFT(type, param) \
- (CAPRI_ ## type ## _PIN_REG_ ## param ## _SHIFT)
-
-#define CAPRI_PIN_MASK(type, param) \
- (CAPRI_ ## type ## _PIN_REG_ ## param ## _MASK)
-
-/*
- * This helper function is used to build up the value and mask used to write to
- * a pin register, but does not actually write to the register.
- */
-static inline void capri_pin_update(u32 *reg_val, u32 *reg_mask, u32 param_val,
- u32 param_shift, u32 param_mask)
-{
- *reg_val &= ~param_mask;
- *reg_val |= (param_val << param_shift) & param_mask;
- *reg_mask |= param_mask;
-}
-
-static struct regmap_config capri_pinctrl_regmap_config = {
- .reg_bits = 32,
- .reg_stride = 4,
- .val_bits = 32,
- .max_register = CAPRI_PIN_VC_CAM3_SDA,
-};
-
-static int capri_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- return pdata->npins;
-}
-
-static const char *capri_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
- unsigned group)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- return pdata->pins[group].name;
-}
-
-static int capri_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
- unsigned group,
- const unsigned **pins,
- unsigned *num_pins)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- *pins = &pdata->pins[group].number;
- *num_pins = 1;
-
- return 0;
-}
-
-static void capri_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
- struct seq_file *s,
- unsigned offset)
-{
- seq_printf(s, " %s", dev_name(pctldev->dev));
-}
-
-static struct pinctrl_ops capri_pinctrl_ops = {
- .get_groups_count = capri_pinctrl_get_groups_count,
- .get_group_name = capri_pinctrl_get_group_name,
- .get_group_pins = capri_pinctrl_get_group_pins,
- .pin_dbg_show = capri_pinctrl_pin_dbg_show,
- .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
- .dt_free_map = pinctrl_utils_dt_free_map,
-};
-
-static int capri_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- return pdata->nfunctions;
-}
-
-static const char *capri_pinctrl_get_fcn_name(struct pinctrl_dev *pctldev,
- unsigned function)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- return pdata->functions[function].name;
-}
-
-static int capri_pinctrl_get_fcn_groups(struct pinctrl_dev *pctldev,
- unsigned function,
- const char * const **groups,
- unsigned * const num_groups)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- *groups = pdata->functions[function].groups;
- *num_groups = pdata->functions[function].ngroups;
-
- return 0;
-}
-
-static int capri_pinmux_enable(struct pinctrl_dev *pctldev,
- unsigned function,
- unsigned group)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
- const struct capri_pin_function *f = &pdata->functions[function];
- u32 offset = 4 * pdata->pins[group].number;
- int rc = 0;
-
- dev_dbg(pctldev->dev,
- "%s(): Enable function %s (%d) of pin %s (%d) @offset 0x%x.\n",
- __func__, f->name, function, pdata->pins[group].name,
- pdata->pins[group].number, offset);
-
- rc = regmap_update_bits(pdata->regmap, offset, CAPRI_PIN_REG_F_SEL_MASK,
- function << CAPRI_PIN_REG_F_SEL_SHIFT);
- if (rc)
- dev_err(pctldev->dev,
- "Error updating register for pin %s (%d).\n",
- pdata->pins[group].name, pdata->pins[group].number);
-
- return rc;
-}
-
-static struct pinmux_ops capri_pinctrl_pinmux_ops = {
- .get_functions_count = capri_pinctrl_get_fcns_count,
- .get_function_name = capri_pinctrl_get_fcn_name,
- .get_function_groups = capri_pinctrl_get_fcn_groups,
- .enable = capri_pinmux_enable,
-};
-
-static int capri_pinctrl_pin_config_get(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *config)
-{
- return -ENOTSUPP;
-}
-
-
-/* Goes through the configs and update register val/mask */
-static int capri_std_pin_update(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *configs,
- unsigned num_configs,
- u32 *val,
- u32 *mask)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
- int i;
- enum pin_config_param param;
- u16 arg;
-
- for (i = 0; i < num_configs; i++) {
- param = pinconf_to_config_param(configs[i]);
- arg = pinconf_to_config_argument(configs[i]);
-
- switch (param) {
- case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
- arg = (arg >= 1 ? 1 : 0);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(STD, HYST),
- CAPRI_PIN_MASK(STD, HYST));
- break;
- /*
- * The pin bias can only be one of pull-up, pull-down, or
- * disable. The user does not need to specify a value for the
- * property, and the default value from pinconf-generic is
- * ignored.
- */
- case PIN_CONFIG_BIAS_DISABLE:
- capri_pin_update(val, mask, 0,
- CAPRI_PIN_SHIFT(STD, PULL_UP),
- CAPRI_PIN_MASK(STD, PULL_UP));
- capri_pin_update(val, mask, 0,
- CAPRI_PIN_SHIFT(STD, PULL_DN),
- CAPRI_PIN_MASK(STD, PULL_DN));
- break;
-
- case PIN_CONFIG_BIAS_PULL_UP:
- capri_pin_update(val, mask, 1,
- CAPRI_PIN_SHIFT(STD, PULL_UP),
- CAPRI_PIN_MASK(STD, PULL_UP));
- capri_pin_update(val, mask, 0,
- CAPRI_PIN_SHIFT(STD, PULL_DN),
- CAPRI_PIN_MASK(STD, PULL_DN));
- break;
-
- case PIN_CONFIG_BIAS_PULL_DOWN:
- capri_pin_update(val, mask, 0,
- CAPRI_PIN_SHIFT(STD, PULL_UP),
- CAPRI_PIN_MASK(STD, PULL_UP));
- capri_pin_update(val, mask, 1,
- CAPRI_PIN_SHIFT(STD, PULL_DN),
- CAPRI_PIN_MASK(STD, PULL_DN));
- break;
-
- case PIN_CONFIG_SLEW_RATE:
- arg = (arg >= 1 ? 1 : 0);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(STD, SLEW),
- CAPRI_PIN_MASK(STD, SLEW));
- break;
-
- case PIN_CONFIG_INPUT_ENABLE:
- /* inversed since register is for input _disable_ */
- arg = (arg >= 1 ? 0 : 1);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(STD, INPUT_DIS),
- CAPRI_PIN_MASK(STD, INPUT_DIS));
- break;
-
- case PIN_CONFIG_DRIVE_STRENGTH:
- /* Valid range is 2-16 mA, even numbers only */
- if ((arg < 2) || (arg > 16) || (arg % 2)) {
- dev_err(pctldev->dev,
- "Invalid Drive Strength value (%d) for "
- "pin %s (%d). Valid values are "
- "(2..16) mA, even numbers only.\n",
- arg, pdata->pins[pin].name, pin);
- return -EINVAL;
- }
- capri_pin_update(val, mask, (arg/2)-1,
- CAPRI_PIN_SHIFT(STD, DRV_STR),
- CAPRI_PIN_MASK(STD, DRV_STR));
- break;
-
- default:
- dev_err(pctldev->dev,
- "Unrecognized pin config %d for pin %s (%d).\n",
- param, pdata->pins[pin].name, pin);
- return -EINVAL;
-
- } /* switch config */
- } /* for each config */
-
- return 0;
-}
-
-/*
- * The pull-up strength for an I2C pin is represented by bits 4-6 in the
- * register with the following mapping:
- * 0b000: No pull-up
- * 0b001: 1200 Ohm
- * 0b010: 1800 Ohm
- * 0b011: 720 Ohm
- * 0b100: 2700 Ohm
- * 0b101: 831 Ohm
- * 0b110: 1080 Ohm
- * 0b111: 568 Ohm
- * This array maps pull-up strength in Ohms to register values (1+index).
- */
-static const u16 capri_pullup_map[] = {1200, 1800, 720, 2700, 831, 1080, 568};
-
-/* Goes through the configs and update register val/mask */
-static int capri_i2c_pin_update(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *configs,
- unsigned num_configs,
- u32 *val,
- u32 *mask)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
- int i, j;
- enum pin_config_param param;
- u16 arg;
-
- for (i = 0; i < num_configs; i++) {
- param = pinconf_to_config_param(configs[i]);
- arg = pinconf_to_config_argument(configs[i]);
-
- switch (param) {
- case PIN_CONFIG_BIAS_PULL_UP:
- for (j = 0; j < ARRAY_SIZE(capri_pullup_map); j++)
- if (capri_pullup_map[j] == arg)
- break;
-
- if (j == ARRAY_SIZE(capri_pullup_map)) {
- dev_err(pctldev->dev,
- "Invalid pull-up value (%d) for pin %s "
- "(%d). Valid values are 568, 720, 831, "
- "1080, 1200, 1800, 2700 Ohms.\n",
- arg, pdata->pins[pin].name, pin);
- return -EINVAL;
- }
-
- capri_pin_update(val, mask, j+1,
- CAPRI_PIN_SHIFT(I2C, PULL_UP_STR),
- CAPRI_PIN_MASK(I2C, PULL_UP_STR));
- break;
-
- case PIN_CONFIG_BIAS_DISABLE:
- capri_pin_update(val, mask, 0,
- CAPRI_PIN_SHIFT(I2C, PULL_UP_STR),
- CAPRI_PIN_MASK(I2C, PULL_UP_STR));
- break;
-
- case PIN_CONFIG_SLEW_RATE:
- arg = (arg >= 1 ? 1 : 0);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(I2C, SLEW),
- CAPRI_PIN_MASK(I2C, SLEW));
- break;
-
- case PIN_CONFIG_INPUT_ENABLE:
- /* inversed since register is for input _disable_ */
- arg = (arg >= 1 ? 0 : 1);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(I2C, INPUT_DIS),
- CAPRI_PIN_MASK(I2C, INPUT_DIS));
- break;
-
- default:
- dev_err(pctldev->dev,
- "Unrecognized pin config %d for pin %s (%d).\n",
- param, pdata->pins[pin].name, pin);
- return -EINVAL;
-
- } /* switch config */
- } /* for each config */
-
- return 0;
-}
-
-/* Goes through the configs and update register val/mask */
-static int capri_hdmi_pin_update(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *configs,
- unsigned num_configs,
- u32 *val,
- u32 *mask)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
- int i;
- enum pin_config_param param;
- u16 arg;
-
- for (i = 0; i < num_configs; i++) {
- param = pinconf_to_config_param(configs[i]);
- arg = pinconf_to_config_argument(configs[i]);
-
- switch (param) {
- case PIN_CONFIG_SLEW_RATE:
- arg = (arg >= 1 ? 1 : 0);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(HDMI, MODE),
- CAPRI_PIN_MASK(HDMI, MODE));
- break;
-
- case PIN_CONFIG_INPUT_ENABLE:
- /* inversed since register is for input _disable_ */
- arg = (arg >= 1 ? 0 : 1);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(HDMI, INPUT_DIS),
- CAPRI_PIN_MASK(HDMI, INPUT_DIS));
- break;
-
- default:
- dev_err(pctldev->dev,
- "Unrecognized pin config %d for pin %s (%d).\n",
- param, pdata->pins[pin].name, pin);
- return -EINVAL;
-
- } /* switch config */
- } /* for each config */
-
- return 0;
-}
-
-static int capri_pinctrl_pin_config_set(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *configs,
- unsigned num_configs)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
- enum capri_pin_type pin_type;
- u32 offset = 4 * pin;
- u32 cfg_val, cfg_mask;
- int rc;
-
- cfg_val = 0;
- cfg_mask = 0;
- pin_type = pin_type_get(pctldev, pin);
-
- /* Different pins have different configuration options */
- switch (pin_type) {
- case CAPRI_PIN_TYPE_STD:
- rc = capri_std_pin_update(pctldev, pin, configs, num_configs,
- &cfg_val, &cfg_mask);
- break;
-
- case CAPRI_PIN_TYPE_I2C:
- rc = capri_i2c_pin_update(pctldev, pin, configs, num_configs,
- &cfg_val, &cfg_mask);
- break;
-
- case CAPRI_PIN_TYPE_HDMI:
- rc = capri_hdmi_pin_update(pctldev, pin, configs, num_configs,
- &cfg_val, &cfg_mask);
- break;
-
- default:
- dev_err(pctldev->dev, "Unknown pin type for pin %s (%d).\n",
- pdata->pins[pin].name, pin);
- return -EINVAL;
-
- } /* switch pin type */
-
- if (rc)
- return rc;
-
- dev_dbg(pctldev->dev,
- "%s(): Set pin %s (%d) with config 0x%x, mask 0x%x\n",
- __func__, pdata->pins[pin].name, pin, cfg_val, cfg_mask);
-
- rc = regmap_update_bits(pdata->regmap, offset, cfg_mask, cfg_val);
- if (rc) {
- dev_err(pctldev->dev,
- "Error updating register for pin %s (%d).\n",
- pdata->pins[pin].name, pin);
- return rc;
- }
-
- return 0;
-}
-
-static struct pinconf_ops capri_pinctrl_pinconf_ops = {
- .pin_config_get = capri_pinctrl_pin_config_get,
- .pin_config_set = capri_pinctrl_pin_config_set,
-};
-
-static struct pinctrl_desc capri_pinctrl_desc = {
- /* name, pins, npins members initialized in probe function */
- .pctlops = &capri_pinctrl_ops,
- .pmxops = &capri_pinctrl_pinmux_ops,
- .confops = &capri_pinctrl_pinconf_ops,
- .owner = THIS_MODULE,
-};
-
-int __init capri_pinctrl_probe(struct platform_device *pdev)
-{
- struct capri_pinctrl_data *pdata = &capri_pinctrl;
- struct resource *res;
- struct pinctrl_dev *pctl;
-
- /* So far We can assume there is only 1 bank of registers */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "Missing MEM resource\n");
- return -ENODEV;
- }
-
- pdata->reg_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(pdata->reg_base)) {
- dev_err(&pdev->dev, "Failed to ioremap MEM resource\n");
- return -ENODEV;
- }
-
- /* Initialize the dynamic part of pinctrl_desc */
- pdata->regmap = devm_regmap_init_mmio(&pdev->dev, pdata->reg_base,
- &capri_pinctrl_regmap_config);
- if (IS_ERR(pdata->regmap)) {
- dev_err(&pdev->dev, "Regmap MMIO init failed.\n");
- return -ENODEV;
- }
-
- capri_pinctrl_desc.name = dev_name(&pdev->dev);
- capri_pinctrl_desc.pins = capri_pinctrl.pins;
- capri_pinctrl_desc.npins = capri_pinctrl.npins;
-
- pctl = pinctrl_register(&capri_pinctrl_desc,
- &pdev->dev,
- pdata);
- if (!pctl) {
- dev_err(&pdev->dev, "Failed to register pinctrl\n");
- return -ENODEV;
- }
-
- platform_set_drvdata(pdev, pdata);
-
- return 0;
-}
-
-static struct of_device_id capri_pinctrl_of_match[] = {
- { .compatible = "brcm,bcm11351-pinctrl", },
- { },
-};
-
-static struct platform_driver capri_pinctrl_driver = {
- .driver = {
- .name = "bcm-capri-pinctrl",
- .owner = THIS_MODULE,
- .of_match_table = capri_pinctrl_of_match,
- },
-};
-
-module_platform_driver_probe(capri_pinctrl_driver, capri_pinctrl_probe);
-
-MODULE_AUTHOR("Sherman Yin <syin@broadcom.com>");
-MODULE_DESCRIPTION("Broadcom Capri pinctrl driver");
-MODULE_LICENSE("GPL v2");
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->intr_status_reg);
- val &= ~BIT(g->intr_status_bit);
+ if (g->intr_ack_high)
+ val |= BIT(g->intr_status_bit);
+ else
+ val &= ~BIT(g->intr_status_bit);
writel(val, pctrl->regs + g->intr_status_reg);
if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
break;
case IRQ_TYPE_EDGE_BOTH:
val |= BIT(g->intr_detection_bit);
+ val |= BIT(g->intr_polarity_bit);
break;
case IRQ_TYPE_LEVEL_LOW:
break;
unsigned intr_enable_bit:5;
unsigned intr_status_bit:5;
+ unsigned intr_ack_high:1;
unsigned intr_target_bit:5;
unsigned intr_raw_status_bit:5;
struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
u32 status;
- pr_err("PLONK IRQ %d\n", irq);
clk_enable(nmk_chip->clk);
status = readl(nmk_chip->addr + NMK_GPIO_IS);
clk_disable(nmk_chip->clk);
* @pin: pin to change
* @mux: new mux function to set
*/
-static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
{
struct rockchip_pinctrl *info = bank->drvdata;
void __iomem *reg = info->reg_base + info->ctrl->mux_offset;
u8 bit;
u32 data;
+ /*
+ * The first 16 pins of rk3188_bank0 are always gpios and do not have
+ * a mux register at all.
+ */
+ if (bank->bank_type == RK3188_BANK0 && pin < 16) {
+ if (mux != RK_FUNC_GPIO) {
+ dev_err(info->dev,
+ "pin %d only supports a gpio mux\n", pin);
+ return -ENOTSUPP;
+ } else {
+ return 0;
+ }
+ }
+
dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
bank->bank_num, pin, mux);
writel(data, reg);
spin_unlock_irqrestore(&bank->slock, flags);
+
+ return 0;
}
#define RK2928_PULL_OFFSET 0x118
const unsigned int *pins = info->groups[group].pins;
const struct rockchip_pin_config *data = info->groups[group].data;
struct rockchip_pin_bank *bank;
- int cnt;
+ int cnt, ret = 0;
dev_dbg(info->dev, "enable function %s group %s\n",
info->functions[selector].name, info->groups[group].name);
*/
for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
bank = pin_to_bank(info, pins[cnt]);
- rockchip_set_mux(bank, pins[cnt] - bank->pin_base,
- data[cnt].func);
+ ret = rockchip_set_mux(bank, pins[cnt] - bank->pin_base,
+ data[cnt].func);
+ if (ret)
+ break;
+ }
+
+ if (ret) {
+ /* revert the already done pin settings */
+ for (cnt--; cnt >= 0; cnt--)
+ rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
+
+ return ret;
}
return 0;
struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct rockchip_pin_bank *bank;
struct gpio_chip *chip;
- int pin;
+ int pin, ret;
u32 data;
chip = range->gc;
dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
offset, range->name, pin, input ? "input" : "output");
- rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
+ ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
+ if (ret < 0)
+ return ret;
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
/* set bit to 1 for output, 0 for input */
u32 polarity;
u32 level;
u32 data;
+ int ret;
/* make sure the pin is configured as gpio input */
- rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
+ ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
+ if (ret < 0)
+ return ret;
+
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
data &= ~mask;
writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
.nr_banks = ARRAY_SIZE(rk3188_pin_banks),
.label = "RK3188-GPIO",
.type = RK3188,
- .mux_offset = 0x68,
+ .mux_offset = 0x60,
.pull_calc_reg = rk3188_calc_pull_reg_and_bit,
};
pdev_bus_addr = r->start;
pdev_bus_len = resource_size(r);
- if (request_mem_region(pdev_bus_addr, pdev_bus_len, "goldfish")) {
- dev_err(&pdev->dev, "unable to reserve Goldfish MMIO.\n");
- return -EBUSY;
- }
-
pdev_bus_base = ioremap(pdev_bus_addr, pdev_bus_len);
if (pdev_bus_base == NULL) {
ret = -ENOMEM;
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/pci.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/pnp.h>
}
#endif
+#ifdef CONFIG_X86
+/* Device IDs of parts that have 32KB MCH space */
+static const unsigned int mch_quirk_devices[] = {
+ 0x0154, /* Ivy Bridge */
+ 0x0c00, /* Haswell */
+};
+
+static struct pci_dev *get_intel_host(void)
+{
+ int i;
+ struct pci_dev *host;
+
+ for (i = 0; i < ARRAY_SIZE(mch_quirk_devices); i++) {
+ host = pci_get_device(PCI_VENDOR_ID_INTEL, mch_quirk_devices[i],
+ NULL);
+ if (host)
+ return host;
+ }
+ return NULL;
+}
+
+static void quirk_intel_mch(struct pnp_dev *dev)
+{
+ struct pci_dev *host;
+ u32 addr_lo, addr_hi;
+ struct pci_bus_region region;
+ struct resource mch;
+ struct pnp_resource *pnp_res;
+ struct resource *res;
+
+ host = get_intel_host();
+ if (!host)
+ return;
+
+ /*
+ * MCHBAR is not an architected PCI BAR, so MCH space is usually
+ * reported as a PNP0C02 resource. The MCH space was originally
+ * 16KB, but is 32KB in newer parts. Some BIOSes still report a
+ * PNP0C02 resource that is only 16KB, which means the rest of the
+ * MCH space is consumed but unreported.
+ */
+
+ /*
+ * Read MCHBAR for Host Member Mapped Register Range Base
+ * https://www-ssl.intel.com/content/www/us/en/processors/core/4th-gen-core-family-desktop-vol-2-datasheet
+ * Sec 3.1.12.
+ */
+ pci_read_config_dword(host, 0x48, &addr_lo);
+ region.start = addr_lo & ~0x7fff;
+ pci_read_config_dword(host, 0x4c, &addr_hi);
+ region.start |= (u64) addr_hi << 32;
+ region.end = region.start + 32*1024 - 1;
+
+ memset(&mch, 0, sizeof(mch));
+ mch.flags = IORESOURCE_MEM;
+ pcibios_bus_to_resource(host->bus, &mch, ®ion);
+
+ list_for_each_entry(pnp_res, &dev->resources, list) {
+ res = &pnp_res->res;
+ if (res->end < mch.start || res->start > mch.end)
+ continue; /* no overlap */
+ if (res->start == mch.start && res->end == mch.end)
+ continue; /* exact match */
+
+ dev_info(&dev->dev, FW_BUG "PNP resource %pR covers only part of %s Intel MCH; extending to %pR\n",
+ res, pci_name(host), &mch);
+ res->start = mch.start;
+ res->end = mch.end;
+ break;
+ }
+
+ pci_dev_put(host);
+}
+#endif
+
/*
* PnP Quirks
* Cards or devices that need some tweaking due to incomplete resource info
{"PNP0c02", quirk_system_pci_resources},
#ifdef CONFIG_AMD_NB
{"PNP0c01", quirk_amd_mmconfig_area},
+#endif
+#ifdef CONFIG_X86
+ {"PNP0c02", quirk_intel_mch},
#endif
{""}
};
* Copyright (C) 2012 ARM Limited
*/
-#include <linux/jiffies.h>
+#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
static void vexpress_reset_do(struct device *dev, const char *what)
{
int err = -ENOENT;
- struct vexpress_config_func *func =
- vexpress_config_func_get_by_dev(dev);
+ struct vexpress_config_func *func = dev_get_drvdata(dev);
if (func) {
- unsigned long timeout;
-
err = vexpress_config_write(func, 0, 0);
-
- timeout = jiffies + HZ;
- while (time_before(jiffies, timeout))
- cpu_relax();
+ if (!err)
+ mdelay(1000);
}
dev_emerg(dev, "Unable to %s (%d)\n", what, err);
enum vexpress_reset_func func;
const struct of_device_id *match =
of_match_device(vexpress_reset_of_match, &pdev->dev);
+ struct vexpress_config_func *config_func;
if (match)
func = (enum vexpress_reset_func)match->data;
else
func = pdev->id_entry->driver_data;
+ config_func = vexpress_config_func_get_by_dev(&pdev->dev);
+ if (!config_func)
+ return -EINVAL;
+ dev_set_drvdata(&pdev->dev, config_func);
+
switch (func) {
case FUNC_SHUTDOWN:
vexpress_power_off_device = &pdev->dev;
* ST Microelectronics SPEAr Pulse Width Modulator driver
*
* Copyright (C) 2012 ST Microelectronics
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
module_platform_driver(spear_pwm_driver);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_AUTHOR("Shiraz Hashim <shiraz.linux.kernel@gmail.com>");
MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.com>");
MODULE_ALIAS("platform:spear-pwm");
struct pbias_regulator_data {
struct regulator_desc desc;
void __iomem *pbias_addr;
- unsigned int pbias_reg;
struct regulator_dev *dev;
struct regmap *syscon;
const struct pbias_reg_info *info;
int voltage;
};
-static int pbias_regulator_set_voltage(struct regulator_dev *dev,
- int min_uV, int max_uV, unsigned *selector)
-{
- struct pbias_regulator_data *data = rdev_get_drvdata(dev);
- const struct pbias_reg_info *info = data->info;
- int ret, vmode;
-
- if (min_uV <= 1800000)
- vmode = 0;
- else if (min_uV > 1800000)
- vmode = info->vmode;
-
- ret = regmap_update_bits(data->syscon, data->pbias_reg,
- info->vmode, vmode);
-
- return ret;
-}
-
-static int pbias_regulator_get_voltage(struct regulator_dev *rdev)
-{
- struct pbias_regulator_data *data = rdev_get_drvdata(rdev);
- const struct pbias_reg_info *info = data->info;
- int value, voltage;
-
- regmap_read(data->syscon, data->pbias_reg, &value);
- value &= info->vmode;
-
- voltage = value ? 3000000 : 1800000;
-
- return voltage;
-}
+static const unsigned int pbias_volt_table[] = {
+ 1800000,
+ 3000000
+};
static int pbias_regulator_enable(struct regulator_dev *rdev)
{
struct pbias_regulator_data *data = rdev_get_drvdata(rdev);
const struct pbias_reg_info *info = data->info;
- int ret;
-
- ret = regmap_update_bits(data->syscon, data->pbias_reg,
- info->enable_mask, info->enable);
-
- return ret;
-}
-
-static int pbias_regulator_disable(struct regulator_dev *rdev)
-{
- struct pbias_regulator_data *data = rdev_get_drvdata(rdev);
- const struct pbias_reg_info *info = data->info;
- int ret;
- ret = regmap_update_bits(data->syscon, data->pbias_reg,
- info->enable_mask, 0);
- return ret;
+ return regmap_update_bits(data->syscon, rdev->desc->enable_reg,
+ info->enable_mask, info->enable);
}
static int pbias_regulator_is_enable(struct regulator_dev *rdev)
const struct pbias_reg_info *info = data->info;
int value;
- regmap_read(data->syscon, data->pbias_reg, &value);
+ regmap_read(data->syscon, rdev->desc->enable_reg, &value);
- return (value & info->enable_mask) == info->enable_mask;
+ return (value & info->enable_mask) == info->enable;
}
static struct regulator_ops pbias_regulator_voltage_ops = {
- .set_voltage = pbias_regulator_set_voltage,
- .get_voltage = pbias_regulator_get_voltage,
- .enable = pbias_regulator_enable,
- .disable = pbias_regulator_disable,
- .is_enabled = pbias_regulator_is_enable,
+ .list_voltage = regulator_list_voltage_table,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .enable = pbias_regulator_enable,
+ .disable = regulator_disable_regmap,
+ .is_enabled = pbias_regulator_is_enable,
};
static const struct pbias_reg_info pbias_mmc_omap2430 = {
if (IS_ERR(syscon))
return PTR_ERR(syscon);
+ cfg.regmap = syscon;
cfg.dev = &pdev->dev;
for (idx = 0; idx < PBIAS_NUM_REGS && data_idx < count; idx++) {
if (!res)
return -EINVAL;
- drvdata[data_idx].pbias_reg = res->start;
drvdata[data_idx].syscon = syscon;
drvdata[data_idx].info = info;
drvdata[data_idx].desc.name = info->name;
drvdata[data_idx].desc.owner = THIS_MODULE;
drvdata[data_idx].desc.type = REGULATOR_VOLTAGE;
drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops;
+ drvdata[data_idx].desc.volt_table = pbias_volt_table;
drvdata[data_idx].desc.n_voltages = 2;
drvdata[data_idx].desc.enable_time = info->enable_time;
+ drvdata[data_idx].desc.vsel_reg = res->start;
+ drvdata[data_idx].desc.vsel_mask = info->vmode;
+ drvdata[data_idx].desc.enable_reg = res->start;
+ drvdata[data_idx].desc.enable_mask = info->enable_mask;
cfg.init_data = pbias_matches[idx].init_data;
cfg.driver_data = &drvdata[data_idx];
return rc;
sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0);
- rc = PTR_RET(sclp_pdev);
+ rc = PTR_ERR_OR_ZERO(sclp_pdev);
if (rc)
goto fail_platform_driver_unregister;
if (rc)
goto out;
sclp_pdev = platform_device_register_simple("sclp_mem", -1, NULL, 0);
- rc = PTR_RET(sclp_pdev);
+ rc = PTR_ERR_OR_ZERO(sclp_pdev);
if (rc)
goto out_driver;
sclp_add_standby_memory();
static int __sclp_vt220_emit(struct sclp_vt220_request *request);
static void sclp_vt220_emit_current(void);
-/* Registration structure for our interest in SCLP event buffers */
+/* Registration structure for SCLP output event buffers */
static struct sclp_register sclp_vt220_register = {
.send_mask = EVTYP_VT220MSG_MASK,
+ .pm_event_fn = sclp_vt220_pm_event_fn,
+};
+
+/* Registration structure for SCLP input event buffers */
+static struct sclp_register sclp_vt220_register_input = {
.receive_mask = EVTYP_VT220MSG_MASK,
- .state_change_fn = NULL,
.receiver_fn = sclp_vt220_receiver_fn,
- .pm_event_fn = sclp_vt220_pm_event_fn,
};
rc = tty_register_driver(driver);
if (rc)
goto out_init;
+ rc = sclp_register(&sclp_vt220_register_input);
+ if (rc)
+ goto out_reg;
sclp_vt220_driver = driver;
return 0;
+out_reg:
+ tty_unregister_driver(driver);
out_init:
__sclp_vt220_cleanup();
out_driver:
if (hpsa_simple_mode)
return;
+ trans_support = readl(&(h->cfgtable->TransportSupport));
+ if (!(trans_support & PERFORMANT_MODE))
+ return;
+
/* Check for I/O accelerator mode support */
if (trans_support & CFGTBL_Trans_io_accel1) {
transMethod |= CFGTBL_Trans_io_accel1 |
}
/* TODO, check that this next line h->nreply_queues is correct */
- trans_support = readl(&(h->cfgtable->TransportSupport));
- if (!(trans_support & PERFORMANT_MODE))
- return;
-
h->nreply_queues = h->msix_vector > 0 ? h->msix_vector : 1;
hpsa_get_max_perf_mode_cmds(h);
/* Performant mode ring buffer and supporting data structures */
/*
* Retry after abort failed, escalate to next level.
*/
+ scmd->eh_eflags &= ~SCSI_EH_ABORT_SCHEDULED;
SCSI_LOG_ERROR_RECOVERY(3,
scmd_printk(KERN_INFO, scmd,
"scmd %p previous abort failed\n", scmd));
ses->prot_op = scmd->prot_op;
scmd->prot_op = SCSI_PROT_NORMAL;
+ scmd->eh_eflags = 0;
scmd->cmnd = ses->eh_cmnd;
memset(scmd->cmnd, 0, BLK_MAX_CDB);
memset(&scmd->sdb, 0, sizeof(scmd->sdb));
scmd->request->next_rq = NULL;
+ scmd->result = 0;
if (sense_bytes) {
scmd->sdb.length = min_t(unsigned, SCSI_SENSE_BUFFERSIZE,
__func__));
break;
}
+ if (status_byte(scmd->result) != CHECK_CONDITION)
+ /*
+ * don't request sense if there's no check condition
+ * status because the error we're processing isn't one
+ * that has a sense code (and some devices get
+ * confused by sense requests out of the blue)
+ */
+ continue;
+
SCSI_LOG_ERROR_RECOVERY(2, scmd_printk(KERN_INFO, scmd,
"%s: requesting sense\n",
current->comm));
* lock such that the kblockd_schedule_work() call happens
* before blk_cleanup_queue() finishes.
*/
+ cmd->result = 0;
spin_lock_irqsave(q->queue_lock, flags);
blk_requeue_request(q, cmd->request);
kblockd_schedule_work(q, &device->requeue_work);
*/
int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask)
{
+ struct scsi_device *sdev = cmd->device;
struct request *rq = cmd->request;
int error = scsi_init_sgtable(rq, &cmd->sdb, gfp_mask);
scsi_release_buffers(cmd);
cmd->request->special = NULL;
scsi_put_command(cmd);
- put_device(&cmd->device->sdev_gendev);
+ put_device(&sdev->sdev_gendev);
return error;
}
EXPORT_SYMBOL(scsi_init_io);
struct scsi_cmnd *cmd = req->special;
scsi_release_buffers(cmd);
scsi_put_command(cmd);
- put_device(&cmd->device->sdev_gendev);
+ put_device(&sdev->sdev_gendev);
req->special = NULL;
}
break;
atmel_spi_next_xfer_pio(master, xfer);
}
+ /* interrupts are disabled, so free the lock for schedule */
+ atmel_spi_unlock(as);
ret = wait_for_completion_timeout(&as->xfer_completion,
SPI_DMA_TIMEOUT);
+ atmel_spi_lock(as);
if (WARN_ON(ret == 0)) {
dev_err(&spi->dev,
"spi trasfer timeout, err %d\n", ret);
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/device.h>
+#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/ioport.h>
return -ENOMEM;
}
- clk = clk_get(NULL, "shyway_clk");
+ clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) {
- dev_err(&pdev->dev, "shyway_clk is required\n");
+ dev_err(&pdev->dev, "couldn't get clock\n");
ret = -EINVAL;
goto error0;
}
sspi->left_rx_word)
sspi->rx_word(sspi);
- if (spi_stat & (SIRFSOC_SPI_FIFO_EMPTY
- | SIRFSOC_SPI_TXFIFO_THD_REACH))
+ if (spi_stat & (SIRFSOC_SPI_TXFIFO_EMPTY |
+ SIRFSOC_SPI_TXFIFO_THD_REACH))
while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS)
& SIRFSOC_SPI_FIFO_FULL)) &&
sspi->left_tx_word)
writel(regval, sspi->base + SIRFSOC_SPI_CTRL);
} else {
int gpio = sspi->chipselect[spi->chip_select];
- gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1);
+ switch (value) {
+ case BITBANG_CS_ACTIVE:
+ gpio_direction_output(gpio,
+ spi->mode & SPI_CS_HIGH ? 1 : 0);
+ break;
+ case BITBANG_CS_INACTIVE:
+ gpio_direction_output(gpio,
+ spi->mode & SPI_CS_HIGH ? 0 : 1);
+ break;
+ }
}
}
regval &= ~SIRFSOC_SPI_CMD_MODE;
sspi->tx_by_cmd = false;
}
+ /*
+ * set spi controller in RISC chipselect mode, we are controlling CS by
+ * software BITBANG_CS_ACTIVE and BITBANG_CS_INACTIVE.
+ */
+ regval |= SIRFSOC_SPI_CS_IO_MODE;
writel(regval, sspi->base + SIRFSOC_SPI_CTRL);
if (IS_DMA_VALID(t)) {
source "drivers/staging/panel/Kconfig"
-source "drivers/staging/rtl8187se/Kconfig"
-
source "drivers/staging/rtl8192u/Kconfig"
source "drivers/staging/rtl8192e/Kconfig"
source "drivers/staging/quickstart/Kconfig"
-source "drivers/staging/sbe-2t3e3/Kconfig"
-
source "drivers/staging/keucr/Kconfig"
source "drivers/staging/bcm/Kconfig"
source "drivers/staging/nokia_h4p/Kconfig"
+source "drivers/staging/skein/Kconfig"
+
source "drivers/staging/unisys/Kconfig"
endif # STAGING
obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
obj-$(CONFIG_PANEL) += panel/
-obj-$(CONFIG_R8187SE) += rtl8187se/
obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_FB_XGI) += xgifb/
obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/
obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/
-obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/
obj-$(CONFIG_USB_ENESTORAGE) += keucr/
obj-$(CONFIG_BCM_WIMAX) += bcm/
obj-$(CONFIG_FT1000) += ft1000/
obj-$(CONFIG_MTD_SPINAND_MT29F) += mt29f_spinand/
obj-$(CONFIG_GS_FPGABOOT) += gs_fpgaboot/
obj-$(CONFIG_BT_NOKIA_H4P) += nokia_h4p/
+obj-$(CONFIG_CRYPTO_SKEIN) += skein/
obj-$(CONFIG_UNISYSSPAR) += unisys/
if (file->private_data) {
for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
uint32_t alarm_type_mask = 1U << i;
+
if (alarm_enabled & alarm_type_mask) {
alarm_dbg(INFO,
"%s: clear alarm, pending %d\n",
struct kernel_param *kp)
{
int ret;
+
ret = param_set_int(val, kp);
if (binder_stop_on_user_error < 2)
wake_up(&binder_user_error_wait);
struct binder_transaction_log *log)
{
struct binder_transaction_log_entry *e;
+
e = &log->entry[log->next];
memset(e, 0, sizeof(*e));
log->next++;
static void binder_set_nice(long nice)
{
long min_nice;
+
if (can_nice(current, nice)) {
set_user_nice(current, nice);
return;
for (page_addr = start; page_addr < end; page_addr += PAGE_SIZE) {
int ret;
struct page **page_array_ptr;
+
page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE];
BUG_ON(*page);
binder_insert_allocated_buffer(proc, buffer);
if (buffer_size != size) {
struct binder_buffer *new_buffer = (void *)buffer->data + size;
+
list_add(&new_buffer->entry, &buffer->entry);
new_buffer->free = 1;
binder_insert_free_buffer(proc, new_buffer);
if (!list_is_last(&buffer->entry, &proc->buffers)) {
struct binder_buffer *next = list_entry(buffer->entry.next,
struct binder_buffer, entry);
+
if (next->free) {
rb_erase(&next->rb_node, &proc->free_buffers);
binder_delete_free_buffer(proc, next);
if (proc->buffers.next != &buffer->entry) {
struct binder_buffer *prev = list_entry(buffer->entry.prev,
struct binder_buffer, entry);
+
if (prev->free) {
binder_delete_free_buffer(proc, buffer);
rb_erase(&prev->rb_node, &proc->free_buffers);
struct list_head *target_list)
{
int ret;
+
if (strong) {
if (ref->strong == 0) {
ret = binder_inc_node(ref->node, 1, 1, target_list);
ref->strong--;
if (ref->strong == 0) {
int ret;
+
ret = binder_dec_node(ref->node, strong, 1);
if (ret)
return ret;
uint32_t error_code)
{
struct binder_thread *target_thread;
+
BUG_ON(t->flags & TF_ONE_WAY);
while (1) {
target_thread = t->from;
off_end = (void *)offp + buffer->offsets_size;
for (; offp < off_end; offp++) {
struct flat_binder_object *fp;
+
if (*offp > buffer->data_size - sizeof(*fp) ||
buffer->data_size < sizeof(*fp) ||
!IS_ALIGNED(*offp, sizeof(u32))) {
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER: {
struct binder_node *node = binder_get_node(proc, fp->binder);
+
if (node == NULL) {
pr_err("transaction release %d bad node %016llx\n",
debug_id, (u64)fp->binder);
case BINDER_TYPE_HANDLE:
case BINDER_TYPE_WEAK_HANDLE: {
struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+
if (ref == NULL) {
pr_err("transaction release %d bad handle %d\n",
debug_id, fp->handle);
} else {
if (tr->target.handle) {
struct binder_ref *ref;
+
ref = binder_get_ref(proc, tr->target.handle);
if (ref == NULL) {
binder_user_error("%d:%d got transaction to invalid handle\n",
}
if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {
struct binder_transaction *tmp;
+
tmp = thread->transaction_stack;
if (tmp->to_thread != thread) {
binder_user_error("%d:%d got new transaction with bad transaction stack, transaction %d has target %d:%d\n",
off_end = (void *)offp + tr->offsets_size;
for (; offp < off_end; offp++) {
struct flat_binder_object *fp;
+
if (*offp > t->buffer->data_size - sizeof(*fp) ||
t->buffer->data_size < sizeof(*fp) ||
!IS_ALIGNED(*offp, sizeof(u32))) {
case BINDER_TYPE_WEAK_BINDER: {
struct binder_ref *ref;
struct binder_node *node = binder_get_node(proc, fp->binder);
+
if (node == NULL) {
node = binder_new_node(proc, fp->binder, fp->cookie);
if (node == NULL) {
case BINDER_TYPE_HANDLE:
case BINDER_TYPE_WEAK_HANDLE: {
struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+
if (ref == NULL) {
binder_user_error("%d:%d got transaction with invalid handle, %d\n",
proc->pid,
(u64)ref->node->ptr);
} else {
struct binder_ref *new_ref;
+
new_ref = binder_get_ref_for_node(target_proc, ref->node);
if (new_ref == NULL) {
return_error = BR_FAILED_REPLY;
{
struct binder_transaction_log_entry *fe;
+
fe = binder_transaction_log_add(&binder_transaction_log_failed);
*fe = *e;
}
struct binder_work *w;
binder_uintptr_t cookie;
struct binder_ref_death *death = NULL;
+
if (get_user(cookie, (binder_uintptr_t __user *)ptr))
return -EFAULT;
ptr += sizeof(void *);
list_for_each_entry(w, &proc->delivered_death, entry) {
struct binder_ref_death *tmp_death = container_of(w, struct binder_ref_death, work);
+
if (tmp_death->cookie == cookie) {
death = tmp_death;
break;
const char *cmd_name;
int strong = node->internal_strong_refs || node->local_strong_refs;
int weak = !hlist_empty(&node->refs) || node->local_weak_refs || strong;
+
if (weak && !node->has_weak_ref) {
cmd = BR_INCREFS;
cmd_name = "BR_INCREFS";
BUG_ON(t->buffer == NULL);
if (t->buffer->target_node) {
struct binder_node *target_node = t->buffer->target_node;
+
tr.target.ptr = target_node->ptr;
tr.cookie = target_node->cookie;
t->saved_priority = task_nice(current);
if (t->from) {
struct task_struct *sender = t->from->proc->tsk;
+
tr.sender_pid = task_tgid_nr_ns(sender,
task_active_pid_ns(current));
} else {
static void binder_release_work(struct list_head *list)
{
struct binder_work *w;
+
while (!list_empty(list)) {
w = list_first_entry(list, struct binder_work, entry);
list_del_init(&w->entry);
switch (cmd) {
case BINDER_WRITE_READ: {
struct binder_write_read bwr;
+
if (size != sizeof(struct binder_write_read)) {
ret = -EINVAL;
goto err;
binder_free_thread(proc, thread);
thread = NULL;
break;
- case BINDER_VERSION:
+ case BINDER_VERSION: {
+ struct binder_version __user *ver = ubuf;
+
if (size != sizeof(struct binder_version)) {
ret = -EINVAL;
goto err;
}
- if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &((struct binder_version *)ubuf)->protocol_version)) {
+ if (put_user(BINDER_CURRENT_PROTOCOL_VERSION,
+ &ver->protocol_version)) {
ret = -EINVAL;
goto err;
}
break;
+ }
default:
ret = -EINVAL;
goto err;
static void binder_vma_open(struct vm_area_struct *vma)
{
struct binder_proc *proc = vma->vm_private_data;
+
binder_debug(BINDER_DEBUG_OPEN_CLOSE,
"%d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
proc->pid, vma->vm_start, vma->vm_end,
static void binder_vma_close(struct vm_area_struct *vma)
{
struct binder_proc *proc = vma->vm_private_data;
+
binder_debug(BINDER_DEBUG_OPEN_CLOSE,
"%d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
proc->pid, vma->vm_start, vma->vm_end,
if (binder_debugfs_dir_entry_proc) {
char strbuf[11];
+
snprintf(strbuf, sizeof(strbuf), "%u", proc->pid);
proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO,
binder_debugfs_dir_entry_proc, proc, &binder_proc_fops);
{
struct rb_node *n;
int wake_count = 0;
+
for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) {
struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node);
+
thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN;
if (thread->looper & BINDER_LOOPER_STATE_WAITING) {
wake_up_interruptible(&thread->wait);
static int binder_release(struct inode *nodp, struct file *filp)
{
struct binder_proc *proc = filp->private_data;
+
debugfs_remove(proc->debugfs_entry);
binder_defer_work(proc, BINDER_DEFERRED_RELEASE);
struct files_struct *files;
int defer;
+
do {
binder_lock(__func__);
mutex_lock(&binder_deferred_lock);
while (n) {
struct ion_handle *entry = rb_entry(n, struct ion_handle, node);
+
if (buffer < entry->buffer)
n = n->rb_left;
else if (buffer > entry->buffer)
{
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);
+
if (strcmp(client->name, name))
continue;
serial = max(serial, client->display_serial);
static void ion_dma_buf_release(struct dma_buf *dmabuf)
{
struct ion_buffer *buffer = dmabuf->priv;
+
ion_buffer_put(buffer);
}
static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset)
{
struct ion_buffer *buffer = dmabuf->priv;
+
return buffer->vaddr + offset * PAGE_SIZE;
}
case ION_IOC_IMPORT:
{
struct ion_handle *handle;
+
handle = ion_import_dma_buf(client, data.fd.fd);
if (IS_ERR(handle))
ret = PTR_ERR(handle);
struct ion_client *client = rb_entry(n, struct ion_client,
node);
size_t size = ion_debug_heap_total(client, heap->id);
+
if (!size)
continue;
if (client->task) {
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);
&debug_shrink_fops);
if (!debug_file) {
char buf[256], *path;
+
path = dentry_path(dev->heaps_debug_root, buf, 256);
pr_err("Failed to create heap shrinker debugfs at %s/%s\n",
path, debug_name);
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 (align > PAGE_SIZE)
return -EINVAL;
- table = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
+ table = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
if (!table)
return -ENOMEM;
ret = sg_alloc_table(table, 1, GFP_KERNEL);
if (allocated_size > chunk_heap->size - chunk_heap->allocated)
return -ENOMEM;
- table = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
+ table = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
if (!table)
return -ENOMEM;
ret = sg_alloc_table(table, num_chunks, GFP_KERNEL);
for_each_sg(table->sgl, sg, table->nents, i) {
int npages_this_entry = PAGE_ALIGN(sg->length) / PAGE_SIZE;
struct page *page = sg_page(sg);
+
BUG_ON(i >= npages);
for (j = 0; j < npages_this_entry; j++)
*(tmp++) = page++;
static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot)
{
void *addr = vm_map_ram(pages, num, -1, pgprot);
+
if (!addr)
return -ENOMEM;
memset(addr, 0, PAGE_SIZE * num);
spinlock_t free_lock;
wait_queue_head_t waitqueue;
struct task_struct *task;
+
int (*debug_show)(struct ion_heap *heap, struct seq_file *, void *);
};
static int order_to_index(unsigned int order)
{
int i;
+
for (i = 0; i < num_orders; i++)
if (order == orders[i])
return i;
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 {
__free_pages(page, order);
max_order = info->order;
i++;
}
- table = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
+ table = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
if (!table)
goto err;
for (i = 0; i < num_orders; i++) {
struct ion_page_pool *pool = sys_heap->pools[i];
+
nr_total += ion_page_pool_shrink(pool, gfp_mask, nr_to_scan);
}
struct ion_system_heap,
heap);
int i;
+
for (i = 0; i < num_orders; i++) {
struct ion_page_pool *pool = sys_heap->pools[i];
+
seq_printf(s, "%d order %u highmem pages in pool = %lu total\n",
pool->high_count, pool->order,
(1 << pool->order) * PAGE_SIZE * pool->high_count);
for (i = len >> PAGE_SHIFT; i < (1 << order); i++)
__free_page(page + i);
- table = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
+ table = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
if (!table) {
ret = -ENOMEM;
goto out;
{
if (file->f_mode & FMODE_READ) {
struct logger_reader *reader = file->private_data;
+
return reader->log;
} else
return file->private_data;
size_t off, struct logger_entry *scratch)
{
size_t len = min(sizeof(struct logger_entry), log->size - off);
+
if (len != sizeof(struct logger_entry)) {
memcpy(((void *) scratch), log->buffer + off, len);
memcpy(((void *) scratch) + len, log->buffer,
static long logger_set_version(struct logger_reader *reader, void __user *arg)
{
int version;
+
if (copy_from_user(&version, arg, sizeof(int)))
return -EFAULT;
+++ /dev/null
-/*
- * Copyright (C) 2010 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.
- *
- */
-
-#ifndef _INCLUDE_LINUX_PLATFORM_DATA_RAM_CONSOLE_H_
-#define _INCLUDE_LINUX_PLATFORM_DATA_RAM_CONSOLE_H_
-
-struct ram_console_platform_data {
- const char *bootinfo;
-};
-
-#endif /* _INCLUDE_LINUX_PLATFORM_DATA_RAM_CONSOLE_H_ */
char *str, int size)
{
struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
+
snprintf(str, size, "%d", pt->value);
}
static int sw_sync_release(struct inode *inode, struct file *file)
{
struct sw_sync_timeline *obj = file->private_data;
+
sync_timeline_destroy(&obj->obj);
return 0;
}
list_for_each_safe(pos, n, &fence->pt_list_head) {
struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list);
+
sync_timeline_remove_pt(pt);
}
}
list_for_each_safe(pos, n, &fence->pt_list_head) {
struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list);
+
sync_pt_free(pt);
}
}
unsigned long arg)
{
struct sync_fence *fence = file->private_data;
+
switch (cmd) {
case SYNC_IOC_WAIT:
return sync_fence_ioctl_wait(fence, arg);
static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence)
{
int status = pt->status;
+
seq_printf(s, " %s%spt %s",
fence ? pt->parent->name : "",
fence ? "_" : "",
sync_status_str(status));
if (pt->status) {
struct timeval tv = ktime_to_timeval(pt->timestamp);
+
seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec);
}
if (pt->parent->ops->timeline_value_str &&
pt->parent->ops->pt_value_str) {
char value[64];
+
pt->parent->ops->pt_value_str(pt, value, sizeof(value));
seq_printf(s, ": %s", value);
if (fence) {
if (obj->ops->timeline_value_str) {
char value[64];
+
obj->ops->timeline_value_str(obj, value, sizeof(value));
seq_printf(s, ": %s", value);
} else if (obj->ops->print_obj) {
for (i = 0; i < s.count; i += DUMP_CHUNK) {
if ((s.count - i) > DUMP_CHUNK) {
char c = s.buf[i + DUMP_CHUNK];
+
s.buf[i + DUMP_CHUNK] = 0;
pr_cont("%s", s.buf + i);
s.buf[i + DUMP_CHUNK] = c;
if (hrtimer_active(&data->timer)) {
ktime_t r = hrtimer_get_remaining(&data->timer);
struct timeval t = ktime_to_timeval(r);
+
return t.tv_sec * 1000 + t.tv_usec / 1000;
} else
return 0;
* @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc
* @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc
* @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved
- * carveout heap, allocations are physically
- * contiguous
+ * carveout heap, allocations are physically
+ * contiguous
* @ION_HEAP_TYPE_DMA: memory allocated via DMA API
* @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask
- * is used to identify the heaps, so only 32
- * total heap types are supported
+ * is used to identify the heaps, so only 32
+ * total heap types are supported
*/
enum ion_heap_type {
ION_HEAP_TYPE_SYSTEM,
#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
+#define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8)
/**
* allocation flags - the lower 16 bits are used by core ion, the upper 16
* @align: required alignment of the allocation
* @heap_id_mask: mask of heap ids to allocate from
* @flags: flags passed to heap
- * @handle: pointer that will be populated with a cookie to use to
+ * @handle: pointer that will be populated with a cookie to use to
* refer to this allocation
*
* Provided by userspace as an argument to the ioctl
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "CopyToAdapter : u8CSSpecification : %X\n", psfLocalSet->u8CSSpecification);
switch (psfLocalSet->u8CSSpecification) {
case eCSPacketIPV4:
- {
Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS;
break;
- }
case eCSPacketIPV6:
- {
Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS;
break;
- }
case eCS802_3PacketEthernet:
case eCS802_1QPacketVLAN:
- {
Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3;
break;
- }
case eCSPacketIPV4Over802_1QVLAN:
case eCSPacketIPV4Over802_3Ethernet:
- {
Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS;
Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3;
break;
- }
case eCSPacketIPV6Over802_1QVLAN:
case eCSPacketIPV6Over802_3Ethernet:
- {
Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS;
Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3;
break;
- }
default:
- {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Error in value of CS Classification.. setting default to IP CS\n");
Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS;
break;
}
- }
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "CopyToAdapter : Queue No : %X ETH CS Support : %X , IP CS Support : %X\n",
uiSearchRuleIndex,
} else if (ucDsxType == DSC_ACK) {
switch (psfCSType->u8ClassfierDSCAction) {
case 0: /* DSC Add Classifier */
- {
eClassifierAction = eAddClassifier;
- }
- break;
+ break;
case 1: /* DSC Replace Classifier */
- {
eClassifierAction = eReplaceClassifier;
- }
- break;
+ break;
case 2: /* DSC Delete Classifier */
- {
eClassifierAction = eDeleteClassifier;
- }
- break;
+ break;
default:
- {
eClassifierAction = eInvalidClassifierAction;
}
- }
}
u16PacketClassificationRuleIndex = ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
switch (eClassifierAction) {
case eAddClassifier:
- {
/* Get a Free Classifier Index From Classifier table for this SF to add the Classifier */
/* Contained in this message */
nClassifierIndex = SearchClsid(Adapter, ulSFID, u16PacketClassificationRuleIndex);
"CopyToAdapter: Error The Specified Classifier Already Exists and attempted To Add Classifier with Same PCRI : 0x%x\n",
u16PacketClassificationRuleIndex);
}
- }
- break;
+ break;
case eReplaceClassifier:
- {
/* Get the Classifier Index From Classifier table for this SF and replace existing Classifier */
/* with the new classifier Contained in this message */
nClassifierIndex = SearchClsid(Adapter, ulSFID, u16PacketClassificationRuleIndex);
}
/* Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. */
CopyClassifierRuleToSF(Adapter, psfCSType, uiSearchRuleIndex, nClassifierIndex);
- }
- break;
+ break;
case eDeleteClassifier:
- {
/* Get the Classifier Index From Classifier table for this SF and replace existing Classifier */
/* with the new classifier Contained in this message */
nClassifierIndex = SearchClsid(Adapter, ulSFID, u16PacketClassificationRuleIndex);
/* Delete This classifier */
DeleteClassifierRuleFromSF(Adapter, uiSearchRuleIndex, nClassifierIndex);
- }
- break;
+ break;
default:
- {
/* Invalid Action for classifier */
break;
}
- }
}
/* Repeat parsing Classification Entries to process PHS Rules */
switch (psfCSType->u8PhsDSCAction) {
case eDeleteAllPHSRules:
- {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Deleting All PHS Rules For VCID: 0x%X\n", uVCID);
/* Delete All the PHS rules for this Service flow */
PhsDeleteSFRules(&Adapter->stBCMPhsContext, uVCID);
break;
- }
case eDeletePHSRule:
- {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "PHS DSC Action = Delete PHS Rule\n");
if (psfCSType->cPhsRule.u8PHSI)
PhsDeletePHSRule(&Adapter->stBCMPhsContext, uVCID, psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
break;
- }
default:
- {
if (ucDsxType == DSC_ACK) {
/* BCM_DEBUG_PRINT(CONN_MSG,("Invalid PHS DSC Action For DSC\n",psfCSType->cPhsRule.u8PHSI)); */
break; /* FOr DSC ACK Case PHS DSC Action must be in valid set */
}
- }
/* Proceed To Add PHS rule for DSA_ACK case even if PHS DSC action is unspecified */
/* No Break Here . Intentionally! */
case eAddPHSRule:
case eSetPHSRule:
- {
if (psfCSType->cPhsRule.u8PHSI) {
/* Apply This PHS Rule to all classifiers whose Associated PHSI Match */
unsigned int uiClassifierIndex = 0;
sPhsRule.u8PHSI);
}
}
- }
- break;
+ break;
}
}
INT len);
-int InterfaceFileDownload( PVOID psIntfAdapter,
- struct file *flp,
- unsigned int on_chip_loc);
+int InterfaceFileDownload(PVOID psIntfAdapter,
+ struct file *flp,
+ unsigned int on_chip_loc);
-int InterfaceFileReadbackFromChip( PVOID psIntfAdapter,
- struct file *flp,
- unsigned int on_chip_loc);
+int InterfaceFileReadbackFromChip(PVOID psIntfAdapter,
+ struct file *flp,
+ unsigned int on_chip_loc);
int BcmRDM(PVOID arg,
*/
#include "headers.h"
-static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter, PVOID pvEthPayload, struct bcm_eth_packet_info *pstEthCsPktInfo);
-static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter, struct sk_buff* skb, struct bcm_eth_packet_info *pstEthCsPktInfo, struct bcm_classifier_rule *pstClassifierRule, B_UINT8 EthCSCupport);
+static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter,
+ PVOID pvEthPayload,
+ struct bcm_eth_packet_info *pstEthCsPktInfo);
-static USHORT IpVersion4(struct bcm_mini_adapter *Adapter, struct iphdr *iphd,
- struct bcm_classifier_rule *pstClassifierRule);
+static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter,
+ struct sk_buff *skb,
+ struct bcm_eth_packet_info *pstEthCsPktInfo,
+ struct bcm_classifier_rule *pstClassifierRule,
+ B_UINT8 EthCSCupport);
+
+static USHORT IpVersion4(struct bcm_mini_adapter *Adapter, struct iphdr *iphd,
+ struct bcm_classifier_rule *pstClassifierRule);
static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex);
ulSrcIP = ntohl(ulSrcIP);
if (0 == pstClassifierRule->ucIPSourceAddressLength)
return TRUE;
- for (ucLoopIndex = 0; ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength); ucLoopIndex++)
- {
+ for (ucLoopIndex = 0; ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength); ucLoopIndex++) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Ip Address Mask:0x%x PacketIp:0x%x and Classification:0x%x", (UINT)pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex], (UINT)ulSrcIP, (UINT)pstClassifierRule->stSrcIpAddress.ulIpv6Addr[ucLoopIndex]);
if ((pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex] & ulSrcIP) ==
(pstClassifierRule->stSrcIpAddress.ulIpv4Addr[ucLoopIndex] & pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex]))
- {
return TRUE;
- }
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Ip Address Not Matched");
return false;
return TRUE;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Ip Address 0x%x 0x%x 0x%x ", (UINT)ulDestIP, (UINT)pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex], (UINT)pstClassifierRule->stDestIpAddress.ulIpv4Addr[ucLoopIndex]);
- for (ucLoopIndex = 0; ucLoopIndex < (pstClassifierRule->ucIPDestinationAddressLength); ucLoopIndex++)
- {
+ for (ucLoopIndex = 0; ucLoopIndex < (pstClassifierRule->ucIPDestinationAddressLength); ucLoopIndex++) {
if ((pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex] & ulDestIP) ==
(pstClassifierRule->stDestIpAddress.ulIpv4Addr[ucLoopIndex] & pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex]))
- {
return TRUE;
- }
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Ip Address Not Matched");
return false;
return TRUE;
if (((pstClassifierRule->ucTosMask & ucTypeOfService) <= pstClassifierRule->ucTosHigh) && ((pstClassifierRule->ucTosMask & ucTypeOfService) >= pstClassifierRule->ucTosLow))
- {
return TRUE;
- }
+
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Type Of Service Not Matched");
return false;
}
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
if (0 == pstClassifierRule->ucProtocolLength)
return TRUE;
- for (ucLoopIndex = 0; ucLoopIndex < pstClassifierRule->ucProtocolLength; ucLoopIndex++)
- {
+ for (ucLoopIndex = 0; ucLoopIndex < pstClassifierRule->ucProtocolLength; ucLoopIndex++) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol:0x%X Classification Protocol:0x%X", ucProtocol, pstClassifierRule->ucProtocol[ucLoopIndex]);
if (pstClassifierRule->ucProtocol[ucLoopIndex] == ucProtocol)
- {
return TRUE;
- }
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Not Matched");
return false;
if (0 == pstClassifierRule->ucSrcPortRangeLength)
return TRUE;
- for (ucLoopIndex = 0; ucLoopIndex < pstClassifierRule->ucSrcPortRangeLength; ucLoopIndex++)
- {
+ for (ucLoopIndex = 0; ucLoopIndex < pstClassifierRule->ucSrcPortRangeLength; ucLoopIndex++) {
if (ushSrcPort <= pstClassifierRule->usSrcPortRangeHi[ucLoopIndex] &&
ushSrcPort >= pstClassifierRule->usSrcPortRangeLo[ucLoopIndex])
- {
return TRUE;
- }
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port: %x Not Matched ", ushSrcPort);
return false;
if (0 == pstClassifierRule->ucDestPortRangeLength)
return TRUE;
- for (ucLoopIndex = 0; ucLoopIndex < pstClassifierRule->ucDestPortRangeLength; ucLoopIndex++)
- {
+ for (ucLoopIndex = 0; ucLoopIndex < pstClassifierRule->ucDestPortRangeLength; ucLoopIndex++) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Matching Port:0x%X 0x%X 0x%X", ushDestPort, pstClassifierRule->usDestPortRangeLo[ucLoopIndex], pstClassifierRule->usDestPortRangeHi[ucLoopIndex]);
if (ushDestPort <= pstClassifierRule->usDestPortRangeHi[ucLoopIndex] &&
ushDestPort >= pstClassifierRule->usDestPortRangeLo[ucLoopIndex])
- {
return TRUE;
- }
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dest Port: %x Not Matched", ushDestPort);
return false;
bClassificationSucceed = TRUE;
} while (0);
- if (TRUE == bClassificationSucceed)
- {
+ if (TRUE == bClassificationSucceed) {
INT iMatchedSFQueueIndex = 0;
iMatchedSFQueueIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
if (iMatchedSFQueueIndex >= NO_OF_QUEUES)
- {
bClassificationSucceed = false;
- }
- else
- {
- if (false == Adapter->PackInfo[iMatchedSFQueueIndex].bActive)
- {
- bClassificationSucceed = false;
- }
- }
+ else if (false == Adapter->PackInfo[iMatchedSFQueueIndex].bActive)
+ bClassificationSucceed = false;
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "IpVersion4 <==========");
{
UINT iIndex = 0;
- for (iIndex = 0; iIndex < HiPriority; iIndex++)
- {
+ for (iIndex = 0; iIndex < HiPriority; iIndex++) {
if (!Adapter->PackInfo[iIndex].bValid)
continue;
spin_lock_bh(&Adapter->PackInfo[iIndex].SFQueueLock);
- while (1)
+ while (1) {
// while((UINT)Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost >
-// SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
- {
+// SF_MAX_ALLOWED_PACKETS_TO_BACKUP) {
+
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "uiCurrentBytesOnHost:%x uiMaxBucketSize :%x",
Adapter->PackInfo[iIndex].uiCurrentBytesOnHost,
Adapter->PackInfo[iIndex].uiMaxBucketSize);
((1000*(jiffies - *((B_UINT32 *)(PacketToDrop->cb)+SKB_CB_LATENCY_OFFSET))/HZ) <= Adapter->PackInfo[iIndex].uiMaxLatency))
break;
- if (PacketToDrop)
- {
+ if (PacketToDrop) {
if (netif_msg_tx_err(Adapter))
pr_info(PFX "%s: tx queue %d overlimit\n",
Adapter->dev->name, iIndex);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "=====>");
// down(&Adapter->data_packet_queue_lock);
- for (iQIndex = LowPriority; iQIndex < HiPriority; iQIndex++)
- {
+ for (iQIndex = LowPriority; iQIndex < HiPriority; iQIndex++) {
struct net_device_stats *netstats = &Adapter->dev->stats;
spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
- while (Adapter->PackInfo[iQIndex].FirstTxQueue)
- {
+ while (Adapter->PackInfo[iQIndex].FirstTxQueue) {
PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue;
- if (PacketToDrop)
- {
+ if (PacketToDrop) {
uiTotalPacketLength = PacketToDrop->len;
netstats->tx_dropped++;
- }
- else
+ } else
uiTotalPacketLength = 0;
DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue,
*((UINT32*) (skb->cb) +SKB_CB_TCPACK_OFFSET) = 0;
EThCSGetPktInfo(Adapter, pvEThPayload, &stEthCsPktInfo);
- switch (stEthCsPktInfo.eNwpktEthFrameType)
- {
+ switch (stEthCsPktInfo.eNwpktEthFrameType) {
case eEth802LLCFrame:
- {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802LLCFrame\n");
pIpHeader = pvEThPayload + sizeof(struct bcm_eth_llc_frame);
break;
- }
-
case eEth802LLCSNAPFrame:
- {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802LLC SNAP Frame\n");
pIpHeader = pvEThPayload + sizeof(struct bcm_eth_llc_snap_frame);
break;
- }
case eEth802QVLANFrame:
- {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802.1Q VLANFrame\n");
pIpHeader = pvEThPayload + sizeof(struct bcm_eth_q_frame);
break;
- }
case eEthOtherFrame:
- {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : ETH Other Frame\n");
pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame);
break;
- }
default:
- {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : Unrecognized ETH Frame\n");
pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame);
break;
- }
}
- if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet)
- {
+ if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) {
usCurrFragment = (ntohs(pIpHeader->frag_off) & IP_OFFSET);
if ((ntohs(pIpHeader->frag_off) & IP_MF) || usCurrFragment)
bFragmentedPkt = TRUE;
- if (bFragmentedPkt)
- {
+ if (bFragmentedPkt) {
//Fragmented Packet. Get Frag Classifier Entry.
pstClassifierRule = GetFragIPClsEntry(Adapter, pIpHeader->id, pIpHeader->saddr);
- if (pstClassifierRule)
- {
+ if (pstClassifierRule) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "It is next Fragmented pkt");
bClassificationSucceed = TRUE;
}
- if (!(ntohs(pIpHeader->frag_off) & IP_MF))
- {
+ if (!(ntohs(pIpHeader->frag_off) & IP_MF)) {
//Fragmented Last packet . Remove Frag Classifier Entry
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "This is the last fragmented Pkt");
DelFragIPClsEntry(Adapter, pIpHeader->id, pIpHeader->saddr);
}
}
- for (uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--)
- {
+ for (uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--) {
if (bClassificationSucceed)
break;
//Iterate through all classifiers which are already in order of priority
//to classify the packet until match found
- do
- {
- if (false == Adapter->astClassifierTable[uiLoopIndex].bUsed)
- {
+ do {
+ if (false == Adapter->astClassifierTable[uiLoopIndex].bUsed) {
bClassificationSucceed = false;
break;
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Adapter->PackInfo[%d].bvalid=True\n", uiLoopIndex);
- if (0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection)
- {
+ if (0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection) {
bClassificationSucceed = false;//cannot be processed for classification.
break; // it is a down link connection
}
break;
}
- if (Adapter->PackInfo[uiSfIndex].bEthCSSupport)
- {
+ if (Adapter->PackInfo[uiSfIndex].bEthCSSupport) {
- if (eEthUnsupportedFrame == stEthCsPktInfo.eNwpktEthFrameType)
- {
+ if (eEthUnsupportedFrame == stEthCsPktInfo.eNwpktEthFrameType) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame\n");
bClassificationSucceed = false;
break;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Performing ETH CS Classification on Classifier Rule ID : %x Service Flow ID : %lx\n", pstClassifierRule->uiClassifierRuleIndex, Adapter->PackInfo[uiSfIndex].ulSFID);
bClassificationSucceed = EThCSClassifyPkt(Adapter, skb, &stEthCsPktInfo, pstClassifierRule, Adapter->PackInfo[uiSfIndex].bEthCSSupport);
- if (!bClassificationSucceed)
- {
+ if (!bClassificationSucceed) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : Ethernet CS Classification Failed\n");
break;
}
- }
-
- else // No ETH Supported on this SF
- {
- if (eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType)
- {
+ } else { // No ETH Supported on this SF
+ if (eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF\n");
bClassificationSucceed = false;
break;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Proceeding to IP CS Clasification");
- if (Adapter->PackInfo[uiSfIndex].bIPCSSupport)
- {
+ if (Adapter->PackInfo[uiSfIndex].bIPCSSupport) {
- if (stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket)
- {
+ if (stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet is Not an IP Packet\n");
bClassificationSucceed = false;
break;
} while (0);
}
- if (bClassificationSucceed == TRUE)
- {
+ if (bClassificationSucceed == TRUE) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "CF id : %d, SF ID is =%lu", pstClassifierRule->uiClassifierRuleIndex, pstClassifierRule->ulSFID);
//Store The matched Classifier in SKB
*((UINT32*)(skb->cb)+SKB_CB_CLASSIFICATION_OFFSET) = pstClassifierRule->uiClassifierRuleIndex;
- if ((TCP == pIpHeader->protocol) && !bFragmentedPkt && (ETH_AND_IP_HEADER_LEN + TCP_HEADER_LEN <= skb->len))
- {
+ if ((TCP == pIpHeader->protocol) && !bFragmentedPkt && (ETH_AND_IP_HEADER_LEN + TCP_HEADER_LEN <= skb->len)) {
IpHeaderLength = pIpHeader->ihl;
pTcpHeader = (struct bcm_tcp_header *)(((PUCHAR)pIpHeader)+(IpHeaderLength*4));
TcpHeaderLength = GET_TCP_HEADER_LEN(pTcpHeader->HeaderLength);
if ((pTcpHeader->ucFlags & TCP_ACK) &&
(ntohs(pIpHeader->tot_len) == (IpHeaderLength*4)+(TcpHeaderLength*4)))
- {
*((UINT32*) (skb->cb) + SKB_CB_TCPACK_OFFSET) = TCP_ACK;
- }
}
usIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "index is =%d", usIndex);
//If this is the first fragment of a Fragmented pkt, add this CF. Only This CF should be used for all other fragment of this Pkt.
- if (bFragmentedPkt && (usCurrFragment == 0))
- {
+ if (bFragmentedPkt && (usCurrFragment == 0)) {
//First Fragment of Fragmented Packet. Create Frag CLS Entry
struct bcm_fragmented_packet_info stFragPktInfo;
stFragPktInfo.bUsed = TRUE;
if (pstClassifierRule->ucEthCSSrcMACLen == 0)
return TRUE;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s\n", __FUNCTION__);
- for (i = 0; i < MAC_ADDRESS_SIZE; i++)
- {
+ for (i = 0; i < MAC_ADDRESS_SIZE; i++) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n", i, Mac[i], pstClassifierRule->au8EThCSSrcMAC[i], pstClassifierRule->au8EThCSSrcMACMask[i]);
if ((pstClassifierRule->au8EThCSSrcMAC[i] & pstClassifierRule->au8EThCSSrcMACMask[i]) !=
(Mac[i] & pstClassifierRule->au8EThCSSrcMACMask[i]))
if (pstClassifierRule->ucEthCSDestMACLen == 0)
return TRUE;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s\n", __FUNCTION__);
- for (i = 0; i < MAC_ADDRESS_SIZE; i++)
- {
+ for (i = 0; i < MAC_ADDRESS_SIZE; i++) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n", i, Mac[i], pstClassifierRule->au8EThCSDestMAC[i], pstClassifierRule->au8EThCSDestMACMask[i]);
if ((pstClassifierRule->au8EThCSDestMAC[i] & pstClassifierRule->au8EThCSDestMACMask[i]) !=
(Mac[i] & pstClassifierRule->au8EThCSDestMACMask[i]))
return TRUE;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s SrcEtherType:%x CLS EtherType[0]:%x\n", __FUNCTION__, pstEthCsPktInfo->usEtherType, pstClassifierRule->au8EthCSEtherType[0]);
- if (pstClassifierRule->au8EthCSEtherType[0] == 1)
- {
+ if (pstClassifierRule->au8EthCSEtherType[0] == 1) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s CLS EtherType[1]:%x EtherType[2]:%x\n", __FUNCTION__, pstClassifierRule->au8EthCSEtherType[1], pstClassifierRule->au8EthCSEtherType[2]);
if (memcmp(&pstEthCsPktInfo->usEtherType, &pstClassifierRule->au8EthCSEtherType[1], 2) == 0)
return false;
}
- if (pstClassifierRule->au8EthCSEtherType[0] == 2)
- {
+ if (pstClassifierRule->au8EthCSEtherType[0] == 2) {
if (eEth802LLCFrame != pstEthCsPktInfo->eNwpktEthFrameType)
return false;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s CLS UserPrio:%x CLS VLANID:%x\n", __FUNCTION__, ntohs(*((USHORT *)pstClassifierRule->usUserPriority)), pstClassifierRule->usVLANID);
/* In case FW didn't receive the TLV, the priority field should be ignored */
- if (pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID))
- {
+ if (pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID)) {
if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame)
return false;
bClassificationSucceed = false;
- if (pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_VLANID_VALID))
- {
+ if (pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_VLANID_VALID)) {
if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame)
return false;
USHORT u16Etype = ntohs(((struct bcm_eth_header *)pvEthPayload)->u16Etype);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : Eth Hdr Type : %X\n", u16Etype);
- if (u16Etype > 0x5dc)
- {
+ if (u16Etype > 0x5dc) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : ETH2 Frame\n");
//ETH2 Frame
- if (u16Etype == ETHERNET_FRAMETYPE_802QVLAN)
- {
+ if (u16Etype == ETHERNET_FRAMETYPE_802QVLAN) {
//802.1Q VLAN Header
pstEthCsPktInfo->eNwpktEthFrameType = eEth802QVLANFrame;
u16Etype = ((struct bcm_eth_q_frame *)pvEthPayload)->EthType;
//((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority
- }
- else
- {
+ } else {
pstEthCsPktInfo->eNwpktEthFrameType = eEthOtherFrame;
u16Etype = ntohs(u16Etype);
}
-
- }
- else
- {
+ } else {
//802.2 LLC
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "802.2 LLC Frame\n");
pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCFrame;
pstEthCsPktInfo->ucDSAP = ((struct bcm_eth_llc_frame *)pvEthPayload)->DSAP;
- if (pstEthCsPktInfo->ucDSAP == 0xAA && ((struct bcm_eth_llc_frame *)pvEthPayload)->SSAP == 0xAA)
- {
+ if (pstEthCsPktInfo->ucDSAP == 0xAA && ((struct bcm_eth_llc_frame *)pvEthPayload)->SSAP == 0xAA) {
//SNAP Frame
pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCSNAPFrame;
u16Etype = ((struct bcm_eth_llc_snap_frame *)pvEthPayload)->usEtherType;
#include "headers.h"
-INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, struct bcm_host_stats_mibs *pstHostMibs)
+INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter,
+ struct bcm_host_stats_mibs *pstHostMibs)
{
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
struct bcm_phs_rule *pstPhsRule = NULL;
struct bcm_phs_classifier_table *pstClassifierTable = NULL;
struct bcm_phs_classifier_entry *pstClassifierRule = NULL;
- struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *) &Adapter->stBCMPhsContext;
-
- UINT nClassifierIndex = 0, nPhsTableIndex = 0, nSfIndex = 0, uiIndex = 0;
+ struct bcm_phs_extension *pDeviceExtension = &Adapter->stBCMPhsContext;
+ UINT nClassifierIndex = 0;
+ UINT nPhsTableIndex = 0;
+ UINT nSfIndex = 0;
+ UINT uiIndex = 0;
if (pDeviceExtension == NULL) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, HOST_MIBS, DBG_LVL_ALL, "Invalid Device Extension\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, HOST_MIBS,
+ DBG_LVL_ALL, "Invalid Device Extension\n");
return STATUS_FAILURE;
}
/* Copy the classifier Table */
- for (nClassifierIndex = 0; nClassifierIndex < MAX_CLASSIFIERS; nClassifierIndex++) {
+ for (nClassifierIndex = 0; nClassifierIndex < MAX_CLASSIFIERS;
+ nClassifierIndex++) {
if (Adapter->astClassifierTable[nClassifierIndex].bUsed == TRUE)
- memcpy((PVOID) &pstHostMibs->
- astClassifierTable[nClassifierIndex],
- (PVOID) &Adapter->
- astClassifierTable[nClassifierIndex],
+ memcpy(&pstHostMibs->astClassifierTable[nClassifierIndex],
+ &Adapter->astClassifierTable[nClassifierIndex],
sizeof(struct bcm_mibs_classifier_rule));
}
/* Copy the SF Table */
for (nSfIndex = 0; nSfIndex < NO_OF_QUEUES; nSfIndex++) {
if (Adapter->PackInfo[nSfIndex].bValid) {
- memcpy((PVOID) &pstHostMibs->astSFtable[nSfIndex],
- (PVOID) &Adapter->PackInfo[nSfIndex],
- sizeof(struct bcm_mibs_table));
+ memcpy(&pstHostMibs->astSFtable[nSfIndex],
+ &Adapter->PackInfo[nSfIndex],
+ sizeof(struct bcm_mibs_table));
} else {
/* If index in not valid,
* don't process this for the PHS table.
pstHostMibs->astPhsRulesTable[nPhsTableIndex].
ulSFID = Adapter->PackInfo[nSfIndex].ulSFID;
- memcpy(&pstHostMibs->
- astPhsRulesTable[nPhsTableIndex].u8PHSI,
- &pstPhsRule->u8PHSI, sizeof(struct bcm_phs_rule));
+ memcpy(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI,
+ &pstPhsRule->u8PHSI,
+ sizeof(struct bcm_phs_rule));
nPhsTableIndex++;
}
/* Copy other Host Statistics parameters */
pstHostMibs->stHostInfo.GoodTransmits = Adapter->dev->stats.tx_packets;
pstHostMibs->stHostInfo.GoodReceives = Adapter->dev->stats.rx_packets;
- pstHostMibs->stHostInfo.CurrNumFreeDesc = atomic_read(&Adapter->CurrNumFreeTxDesc);
+ pstHostMibs->stHostInfo.CurrNumFreeDesc =
+ atomic_read(&Adapter->CurrNumFreeTxDesc);
pstHostMibs->stHostInfo.BEBucketSize = Adapter->BEBucketSize;
pstHostMibs->stHostInfo.rtPSBucketSize = Adapter->rtPSBucketSize;
pstHostMibs->stHostInfo.TimerActive = Adapter->TimerActive;
pstHostMibs->stHostInfo.u32TotalDSD = Adapter->u32TotalDSD;
- memcpy(pstHostMibs->stHostInfo.aTxPktSizeHist, Adapter->aTxPktSizeHist, sizeof(UINT32) * MIBS_MAX_HIST_ENTRIES);
- memcpy(pstHostMibs->stHostInfo.aRxPktSizeHist, Adapter->aRxPktSizeHist, sizeof(UINT32) * MIBS_MAX_HIST_ENTRIES);
+ memcpy(pstHostMibs->stHostInfo.aTxPktSizeHist, Adapter->aTxPktSizeHist,
+ sizeof(UINT32) * MIBS_MAX_HIST_ENTRIES);
+ memcpy(pstHostMibs->stHostInfo.aRxPktSizeHist, Adapter->aRxPktSizeHist,
+ sizeof(UINT32) * MIBS_MAX_HIST_ENTRIES);
return STATUS_SUCCESS;
}
-VOID GetDroppedAppCntrlPktMibs(struct bcm_host_stats_mibs *pstHostMibs, struct bcm_tarang_data *pTarang)
+VOID GetDroppedAppCntrlPktMibs(struct bcm_host_stats_mibs *pstHostMibs,
+ struct bcm_tarang_data *pTarang)
{
memcpy(&(pstHostMibs->stDroppedAppCntrlMsgs),
&(pTarang->stDroppedAppCntrlMsgs),
sizeof(struct bcm_mibs_dropped_cntrl_msg));
}
-VOID CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter, struct bcm_connect_mgr_params *psfLocalSet, UINT uiSearchRuleIndex)
+VOID CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter,
+ struct bcm_connect_mgr_params *psfLocalSet,
+ UINT uiSearchRuleIndex)
{
struct bcm_mibs_parameters *t = &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable;
struct comedi_subdevice *s)
{
struct comedi_async *async = s->async;
+ struct comedi_buf_map *bm;
+ unsigned long flags;
if (async->prealloc_buf) {
vunmap(async->prealloc_buf);
async->prealloc_bufsz = 0;
}
- comedi_buf_map_put(async->buf_map);
+ spin_lock_irqsave(&s->spin_lock, flags);
+ bm = async->buf_map;
async->buf_map = NULL;
+ spin_unlock_irqrestore(&s->spin_lock, flags);
+ comedi_buf_map_put(bm);
}
static void __comedi_buf_alloc(struct comedi_device *dev,
struct page **pages = NULL;
struct comedi_buf_map *bm;
struct comedi_buf_page *buf;
+ unsigned long flags;
unsigned i;
if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) {
if (!bm)
return;
- async->buf_map = bm;
kref_init(&bm->refcount);
+ spin_lock_irqsave(&s->spin_lock, flags);
+ async->buf_map = bm;
+ spin_unlock_irqrestore(&s->spin_lock, flags);
bm->dma_dir = s->async_dma_dir;
if (bm->dma_dir != DMA_NONE)
/* Need ref to hardware device to free buffer later. */
pages[i] = virt_to_page(buf->virt_addr);
}
+ spin_lock_irqsave(&s->spin_lock, flags);
bm->n_pages = i;
+ spin_unlock_irqrestore(&s->spin_lock, flags);
/* vmap the prealloc_buf if all the pages were allocated */
if (i == n_pages)
return 1;
}
+/* returns s->async->buf_map and increments its kref refcount */
+struct comedi_buf_map *
+comedi_buf_map_from_subdev_get(struct comedi_subdevice *s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_buf_map *bm = NULL;
+ unsigned long flags;
+
+ if (!async)
+ return NULL;
+
+ spin_lock_irqsave(&s->spin_lock, flags);
+ bm = async->buf_map;
+ /* only want it if buffer pages allocated */
+ if (bm && bm->n_pages)
+ comedi_buf_map_get(bm);
+ else
+ bm = NULL;
+ spin_unlock_irqrestore(&s->spin_lock, flags);
+
+ return bm;
+}
+
bool comedi_buf_is_mmapped(struct comedi_async *async)
{
struct comedi_buf_map *bm = async->buf_map;
}
static int resize_async_buffer(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_async *async, unsigned new_size)
+ struct comedi_subdevice *s, unsigned new_size)
{
+ struct comedi_async *async = s->async;
int retval;
if (new_size > async->max_bufsize)
mutex_lock(&dev->mutex);
s = comedi_read_subdevice(dev, minor);
if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
- err = resize_async_buffer(dev, s, s->async, size);
+ err = resize_async_buffer(dev, s, size);
else
err = -EINVAL;
mutex_unlock(&dev->mutex);
mutex_lock(&dev->mutex);
s = comedi_write_subdevice(dev, minor);
if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
- err = resize_async_buffer(dev, s, s->async, size);
+ err = resize_async_buffer(dev, s, size);
else
err = -EINVAL;
mutex_unlock(&dev->mutex);
return -EBUSY;
if (dev->attached) {
struct module *driver_module = dev->driver->module;
+
comedi_device_detach(dev);
module_put(driver_module);
}
}
if (bc.size) {
- retval = resize_async_buffer(dev, s, async, bc.size);
+ retval = resize_async_buffer(dev, s, bc.size);
if (retval < 0)
return retval;
}
s = &dev->subdevices[cmd->subdev];
if (s->type == COMEDI_SUBD_UNUSED) {
- dev_dbg(dev->class_dev, "%d not valid subdevice\n", cmd->subdev);
+ dev_dbg(dev->class_dev, "%d not valid subdevice\n",
+ cmd->subdev);
return -EIO;
}
if (!s->do_cmd || !s->do_cmdtest || !s->async) {
dev_dbg(dev->class_dev,
- "subdevice %d does not support commands\n", cmd->subdev);
+ "subdevice %d does not support commands\n",
+ cmd->subdev);
return -EIO;
}
{
struct comedi_cmd cmd;
struct comedi_subdevice *s;
- unsigned int *chanlist = NULL;
unsigned int __user *user_chanlist;
int ret;
ret = -EFAULT;
}
- kfree(chanlist);
-
return ret;
}
struct comedi_device *dev = file->private_data;
struct comedi_subdevice *s;
struct comedi_async *async;
- struct comedi_buf_map *bm;
+ struct comedi_buf_map *bm = NULL;
unsigned long start = vma->vm_start;
unsigned long size;
int n_pages;
int i;
int retval;
- mutex_lock(&dev->mutex);
+ /*
+ * 'trylock' avoids circular dependency with current->mm->mmap_sem
+ * and down-reading &dev->attach_lock should normally succeed without
+ * contention unless the device is in the process of being attached
+ * or detached.
+ */
+ if (!down_read_trylock(&dev->attach_lock))
+ return -EAGAIN;
if (!dev->attached) {
dev_dbg(dev->class_dev, "no driver attached\n");
}
n_pages = size >> PAGE_SHIFT;
- bm = async->buf_map;
+
+ /* get reference to current buf map (if any) */
+ bm = comedi_buf_map_from_subdev_get(s);
if (!bm || n_pages > bm->n_pages) {
retval = -EINVAL;
goto done;
retval = 0;
done:
- mutex_unlock(&dev->mutex);
+ up_read(&dev->attach_lock);
+ comedi_buf_map_put(bm); /* put reference to buf map - okay if NULL */
return retval;
}
s = comedi_write_subdevice(dev, minor);
if (s && s->async) {
- unsigned int bps = bytes_per_sample(s->async->subdevice);
+ unsigned int bps = bytes_per_sample(s);
poll_wait(file, &s->async->wait_head, wait);
comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
/* create devices files for legacy/manual use */
for (i = 0; i < comedi_num_legacy_minors; i++) {
struct comedi_device *dev;
+
dev = comedi_alloc_board_minor(NULL);
if (IS_ERR(dev)) {
comedi_cleanup_board_minors();
bool comedi_buf_is_mmapped(struct comedi_async *async);
void comedi_buf_map_get(struct comedi_buf_map *bm);
int comedi_buf_map_put(struct comedi_buf_map *bm);
+struct comedi_buf_map *comedi_buf_map_from_subdev_get(
+ struct comedi_subdevice *s);
unsigned int comedi_buf_write_n_allocated(struct comedi_async *async);
void comedi_device_cancel_all(struct comedi_device *dev);
const unsigned base_bitfield_channel =
(chan < channels_per_bitfield) ? 0 : chan;
unsigned int new_data[2];
+
memset(new_data, 0, sizeof(new_data));
memset(&new_insn, 0, sizeof(new_insn));
new_insn.insn = INSN_BITS;
#define I8254_OSC_BASE_2MHZ 500
#define I8254_OSC_BASE_1MHZ 1000
-#define i8253_cascade_ns_to_timer i8253_cascade_ns_to_timer_2div
-
-static inline void i8253_cascade_ns_to_timer_2div_old(int i8253_osc_base,
- unsigned int *d1,
- unsigned int *d2,
- unsigned int *nanosec,
- int round_mode)
-{
- int divider;
- int div1, div2;
- int div1_glb, div2_glb, ns_glb;
- int div1_lub, div2_lub, ns_lub;
- int ns;
-
- divider = (*nanosec + i8253_osc_base / 2) / i8253_osc_base;
-
- /* find 2 integers 1<={x,y}<=65536 such that x*y is
- close to divider */
-
- div1_lub = div2_lub = 0;
- div1_glb = div2_glb = 0;
-
- ns_glb = 0;
- ns_lub = 0xffffffff;
-
- div2 = 0x10000;
- for (div1 = divider / 65536 + 1; div1 < div2; div1++) {
- div2 = divider / div1;
-
- ns = i8253_osc_base * div1 * div2;
- if (ns <= *nanosec && ns > ns_glb) {
- ns_glb = ns;
- div1_glb = div1;
- div2_glb = div2;
- }
-
- div2++;
- if (div2 <= 65536) {
- ns = i8253_osc_base * div1 * div2;
- if (ns > *nanosec && ns < ns_lub) {
- ns_lub = ns;
- div1_lub = div1;
- div2_lub = div2;
- }
- }
- }
-
- *nanosec = div1_lub * div2_lub * i8253_osc_base;
- *d1 = div1_lub & 0xffff;
- *d2 = div2_lub & 0xffff;
- return;
-}
-
-static inline void i8253_cascade_ns_to_timer_power(int i8253_osc_base,
- unsigned int *d1,
- unsigned int *d2,
- unsigned int *nanosec,
- int round_mode)
-{
- int div1, div2;
- int base;
-
- for (div1 = 2; div1 <= (1 << 16); div1 <<= 1) {
- base = i8253_osc_base * div1;
- round_mode &= TRIG_ROUND_MASK;
- switch (round_mode) {
- case TRIG_ROUND_NEAREST:
- default:
- div2 = (*nanosec + base / 2) / base;
- break;
- case TRIG_ROUND_DOWN:
- div2 = (*nanosec) / base;
- break;
- case TRIG_ROUND_UP:
- div2 = (*nanosec + base - 1) / base;
- break;
- }
- if (div2 < 2)
- div2 = 2;
- if (div2 <= 65536) {
- *nanosec = div2 * base;
- *d1 = div1 & 0xffff;
- *d2 = div2 & 0xffff;
- return;
- }
- }
-
- /* shouldn't get here */
- div1 = 0x10000;
- div2 = 0x10000;
- *nanosec = div1 * div2 * i8253_osc_base;
- *d1 = div1 & 0xffff;
- *d2 = div2 & 0xffff;
-}
-
-static inline void i8253_cascade_ns_to_timer_2div(int i8253_osc_base,
- unsigned int *d1,
- unsigned int *d2,
- unsigned int *nanosec,
- int round_mode)
+static inline void i8253_cascade_ns_to_timer(int i8253_osc_base,
+ unsigned int *d1,
+ unsigned int *d2,
+ unsigned int *nanosec,
+ int round_mode)
{
unsigned int divider;
unsigned int div1, div2;
if (counter_number > 2)
return -1;
- if (mode > (I8254_MODE5 | I8254_BINARY))
+ if (mode > (I8254_MODE5 | I8254_BCD))
return -1;
byte = counter_number << 6;
if (counter_number > 2)
return -1;
- if (mode > (I8254_MODE5 | I8254_BINARY))
+ if (mode > (I8254_MODE5 | I8254_BCD))
return -1;
byte = counter_number << 6;
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
if (ret)
return ret;
+ s->len_chanlist = 1;
s->do_cmdtest = subdev_8255_cmdtest;
s->do_cmd = subdev_8255_cmd;
s->cancel = subdev_8255_cancel;
#include "../comedidev.h"
int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
- int (*io) (int, int, int, unsigned long),
+ int (*io)(int, int, int, unsigned long),
unsigned long iobase);
int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
- int (*io) (int, int, int, unsigned long),
+ int (*io)(int, int, int, unsigned long),
unsigned long iobase);
void subdev_8255_interrupt(struct comedi_device *dev,
struct comedi_subdevice *s);
int i_IobaseAmcc; /* base+size for AMCC chip */
int i_IobaseAddon; /* addon base address */
int i_IobaseReserved;
- unsigned char b_AiContinuous; /* we do unlimited AI */
unsigned int ui_AiActualScan; /* how many scans we finished */
unsigned int ui_AiNbrofChannels; /* how many channels is measured */
- unsigned int ui_AiScanLength; /* Length of actual scanlist */
- unsigned int *pui_AiChannelList; /* actual chanlist */
unsigned int ui_AiChannelList[32]; /* actual chanlist */
unsigned int ui_AiReadData[32];
- unsigned int ui_AiTimer0; /* Timer Constant for Timer0 */
- unsigned int ui_AiTimer1; /* Timer constant for Timer1 */
- unsigned int ui_AiFlags;
- unsigned int ui_AiDataLength;
- unsigned int ui_AiNbrofScans; /* number of scans to do */
unsigned short us_UseDma; /* To use Dma or not */
unsigned char b_DmaDoubleBuffer; /* we can use double buffering */
unsigned int ui_DmaActualBuffer; /* which buffer is used now */
unsigned short us_OutputRegister; /* Contain data written at iobase + 0 */
unsigned char b_Timer2Mode; /* Specify the timer 2 mode */
unsigned char b_Timer2Interrupt; /* Timer2 interrupt enable or disable */
- unsigned char b_AiCyclicAcquisition; /* indicate cyclic acquisition */
+ unsigned int ai_running:1;
unsigned char b_InterruptMode; /* eoc eos or dma */
unsigned char b_EocEosInterrupt; /* Enable disable eoc eos interrupt */
unsigned int ui_EocEosConversionTime;
*
*/
+#include "../addi_watchdog.h"
+
#define APCI1564_ADDRESS_RANGE 128
/* Digital Input IRQ Function Selection */
#define APCI1564_TIMER_WARN_TIMEBASE_REG 0x64
/*
- * devpriv->iobase Register Map
+ * dev>iobase Register Map
*/
#define APCI1564_TCW_REG(x) (0x00 + ((x) * 0x20))
#define APCI1564_TCW_RELOAD_REG(x) (0x04 + ((x) * 0x20))
outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_IRQ_REG);
outl(0x0, devpriv->i_IobaseAmcc + APCI1564_WDOG_IRQ_REG);
outl(0x0,
- devpriv->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1));
+ dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1));
outl(0x0,
- devpriv->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER2));
+ dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER2));
outl(0x0,
- devpriv->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER3));
+ dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER3));
outl(0x0,
- devpriv->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4));
+ dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4));
} else {
/* disable Timer interrupt */
outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
devpriv->b_ModeSelectRegister = data[5];
/* First Stop The Counter */
- ul_Command1 = inl(devpriv->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1));
+ ul_Command1 = inl(dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1));
ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
/* Stop The Timer */
- outl(ul_Command1, devpriv->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1));
+ outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1));
/* Set the reload value */
- outl(data[3], devpriv->iobase + APCI1564_TCW_RELOAD_REG(data[5] - 1));
+ outl(data[3], dev->iobase + APCI1564_TCW_RELOAD_REG(data[5] - 1));
/* Set the mode : */
/* - Disable the hardware */
ul_Command1 =
(ul_Command1 & 0xFFFC19E2UL) | 0x80000UL |
(unsigned int) ((unsigned int) data[4] << 16UL);
- outl(ul_Command1, devpriv->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1));
+ outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1));
/* Enable or Disable Interrupt */
ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1);
- outl(ul_Command1, devpriv->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1));
+ outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1));
/* Set the Up/Down selection */
ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18);
- outl(ul_Command1, devpriv->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1));
+ outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1));
} else {
dev_err(dev->class_dev, "Invalid subdevice.\n");
}
}
if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
ul_Command1 =
- inl(devpriv->iobase +
- APCI1564_TCW_CTRL_REG(devpriv->b_ModeSelectRegister - 1));
+ inl(dev->iobase +
+ APCI1564_TCW_CTRL_REG(devpriv->b_ModeSelectRegister - 1));
if (data[1] == 1) {
/* Start the Counter subdevice */
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
/* Clears the Counter subdevice */
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400;
}
- outl(ul_Command1,
- devpriv->iobase +
- APCI1564_TCW_CTRL_REG(devpriv->b_ModeSelectRegister - 1));
+ outl(ul_Command1, dev->iobase +
+ APCI1564_TCW_CTRL_REG(devpriv->b_ModeSelectRegister - 1));
}
return insn->n;
}
} else if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
/* Read the Counter Actual Value. */
data[0] =
- inl(devpriv->iobase +
- APCI1564_TCW_REG(devpriv->b_ModeSelectRegister - 1));
+ inl(dev->iobase +
+ APCI1564_TCW_REG(devpriv->b_ModeSelectRegister - 1));
ul_Command1 =
- inl(devpriv->iobase +
- APCI1564_TCW_STATUS_REG(devpriv->b_ModeSelectRegister - 1));
+ inl(dev->iobase +
+ APCI1564_TCW_STATUS_REG(devpriv->b_ModeSelectRegister - 1));
/* Get the software trigger status */
data[1] = (unsigned char) ((ul_Command1 >> 1) & 1);
ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DO_IRQ_REG) & 0x01;
ui_Timer = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_IRQ_REG) & 0x01;
ui_C1 =
- inl(devpriv->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1)) & 0x1;
+ inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1)) & 0x1;
ui_C2 =
- inl(devpriv->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER2)) & 0x1;
+ inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER2)) & 0x1;
ui_C3 =
- inl(devpriv->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER3)) & 0x1;
+ inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER3)) & 0x1;
ui_C4 =
- inl(devpriv->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4)) & 0x1;
+ inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4)) & 0x1;
if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0
&& ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) {
dev_err(dev->class_dev, "Interrupt from unknown source.\n");
/* Disable Counter Interrupt */
ul_Command2 =
- inl(devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
+ inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
outl(0x0,
- devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
/* Send a signal to from kernel to user space */
send_sig(SIGIO, devpriv->tsk_Current, 0);
/* Enable Counter Interrupt */
outl(ul_Command2,
- devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
}
}
/* Disable Counter Interrupt */
ul_Command2 =
- inl(devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
+ inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
outl(0x0,
- devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
/* Send a signal to from kernel to user space */
send_sig(SIGIO, devpriv->tsk_Current, 0);
/* Enable Counter Interrupt */
outl(ul_Command2,
- devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
}
}
/* Disable Counter Interrupt */
ul_Command2 =
- inl(devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
+ inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
outl(0x0,
- devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
/* Send a signal to from kernel to user space */
send_sig(SIGIO, devpriv->tsk_Current, 0);
/* Enable Counter Interrupt */
outl(ul_Command2,
- devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
}
}
/* Disable Counter Interrupt */
ul_Command2 =
- inl(devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
+ inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
outl(0x0,
- devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
/* Send a signal to from kernel to user space */
send_sig(SIGIO, devpriv->tsk_Current, 0);
/* Enable Counter Interrupt */
outl(ul_Command2,
- devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
}
}
return;
{
struct addi_private *devpriv = dev->private;
- /* disable the interrupts */
+ ui_Type = 0;
+
+ /* Disable the input interrupts and reset status register */
outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- /* Reset the interrupt status register */
inl(devpriv->i_IobaseAmcc + APCI1564_DI_INT_STATUS_REG);
- /* Disable the and/or interrupt */
outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE1_REG);
outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE2_REG);
- devpriv->b_DigitalOutputRegister = 0;
- ui_Type = 0;
- /* Resets the output channels */
+
+ /* Reset the output channels and disable interrupts */
outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_REG);
- /* Disables the interrupt. */
outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_INT_CTRL_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_WDOG_RELOAD_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_REG);
+
+ /* Reset the watchdog registers */
+ addi_watchdog_reset(devpriv->i_IobaseAmcc + APCI1564_WDOG_REG);
+
+ /* Reset the timer registers */
outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_RELOAD_REG);
+
+ /* Reset the counter registers */
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
- outl(0x0, devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
- outl(0x0, devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
- outl(0x0, devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
- outl(0x0, devpriv->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
return 0;
}
unsigned int i;
unsigned short us_TmpValue;
- devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+ devpriv->ai_running = 0;
devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
devpriv->b_InterruptMode = APCI3120_EOC_MODE;
devpriv->ui_EocEosConversionTime = 0; /* set eoc eos conv time to 0 */
- devpriv->b_OutputMemoryStatus = 0;
/* variables used in timer subdevice */
devpriv->b_Timer2Mode = 0;
inw(dev->iobase + APCI3120_RD_STATUS);
devpriv->ui_AiActualScan = 0;
s->async->cur_chan = 0;
- devpriv->b_AiContinuous = 0;
devpriv->ui_DmaActualBuffer = 0;
- devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+ devpriv->ai_running = 0;
devpriv->b_InterruptMode = APCI3120_EOC_MODE;
devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
apci3120_reset(dev);
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
- const struct addi_board *this_board = comedi_board(dev);
int err = 0;
/* Step 1 : check if triggers are trivially valid */
if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */
err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 100000);
- if (cmd->convert_src == TRIG_TIMER) { /* Test Acquisition timing */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->convert_arg)
- err |= cfc_check_trigger_arg_min(
- &cmd->convert_arg, 10000);
- } else {
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->convert_arg)
err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
- 10000);
- }
+ 10000);
+ } else {
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000);
}
err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= cfc_check_trigger_arg_max(&cmd->chanlist_len,
- this_board->i_AiChannelList);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
if (cmd->stop_src == TRIG_COUNT)
err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
/* step 4: fix up any arguments */
- if (cmd->convert_src == TRIG_TIMER) {
-
- if (cmd->scan_begin_src == TRIG_TIMER &&
- cmd->scan_begin_arg <
- cmd->convert_arg * cmd->scan_end_arg) {
- cmd->scan_begin_arg =
- cmd->convert_arg * cmd->scan_end_arg;
- err++;
- }
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg < cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg = cmd->convert_arg * cmd->scan_end_arg;
+ err |= -EINVAL;
}
if (err)
{
const struct addi_board *this_board = comedi_board(dev);
struct addi_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
unsigned char b_Tmp;
unsigned int ui_Tmp, ui_DelayTiming = 0, ui_TimerValue1 = 0, dmalen0 =
0, dmalen1 = 0, ui_TimerValue2 =
0, ui_TimerValue0, ui_ConvertTiming;
unsigned short us_TmpValue;
- /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */
- /* devpriv->b_AiCyclicAcquisition=APCI3120_ENABLE; */
- /* END JK 07.05.04: Comparison between WIN32 and Linux driver */
-
/*******************/
/* Resets the FIFO */
/*******************/
/* inw(dev->iobase+APCI3120_RD_STATUS); */
/* END JK 07.05.04: Comparison between WIN32 and Linux driver */
- /***************************/
- /* Acquisition initialized */
- /***************************/
- /* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */
- devpriv->b_AiCyclicAcquisition = APCI3120_ENABLE;
- /* END JK 07.05.04: Comparison between WIN32 and Linux driver */
+ devpriv->ai_running = 1;
/* clear software registers */
devpriv->b_TimerSelectMode = 0;
devpriv->ui_DmaActualBuffer = 0;
/* value for timer2 minus -2 has to be done .....dunno y?? */
- ui_TimerValue2 = devpriv->ui_AiNbrofScans - 2;
- ui_ConvertTiming = devpriv->ui_AiTimer0;
+ ui_TimerValue2 = cmd->stop_arg - 2;
+ ui_ConvertTiming = cmd->convert_arg;
if (mode == 2)
- ui_DelayTiming = devpriv->ui_AiTimer1;
+ ui_DelayTiming = cmd->scan_begin_arg;
/**********************************/
/* Initializes the sequence array */
/**********************************/
if (!apci3120_setup_chan_list(dev, s, devpriv->ui_AiNbrofChannels,
- devpriv->pui_AiChannelList, 0))
+ cmd->chanlist, 0))
return -EINVAL;
us_TmpValue = (unsigned short) inw(dev->iobase + APCI3120_RD_STATUS);
outb(devpriv->b_ModeSelectRegister,
dev->iobase + APCI3120_WRITE_MODE_SELECT);
- if (!devpriv->b_AiContinuous) {
+ if (cmd->stop_src == TRIG_COUNT) {
/*
* configure Timer2 For counting EOS Reset gate 2 of Timer 2 to
* disable it (Set Bit D14 to 0)
}
} else {
/* If DMA Enabled */
+ unsigned int scan_bytes = cmd->scan_end_arg * sizeof(short);
/* BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver */
/* inw(dev->iobase+0); reset EOC bit */
dmalen0 = devpriv->ui_DmaBufferSize[0];
dmalen1 = devpriv->ui_DmaBufferSize[1];
- if (!devpriv->b_AiContinuous) {
-
- if (dmalen0 > (devpriv->ui_AiNbrofScans * devpriv->ui_AiScanLength * 2)) { /* must we fill full first buffer? */
- dmalen0 =
- devpriv->ui_AiNbrofScans *
- devpriv->ui_AiScanLength * 2;
- } else if (dmalen1 > (devpriv->ui_AiNbrofScans * devpriv->ui_AiScanLength * 2 - dmalen0)) /* and must we fill full second buffer when first is once filled? */
- dmalen1 =
- devpriv->ui_AiNbrofScans *
- devpriv->ui_AiScanLength * 2 - dmalen0;
+ if (cmd->stop_src == TRIG_COUNT) {
+ /*
+ * Must we fill full first buffer? And must we fill
+ * full second buffer when first is once filled?
+ */
+ if (dmalen0 > (cmd->stop_arg * scan_bytes)) {
+ dmalen0 = cmd->stop_arg * scan_bytes;
+ } else if (dmalen1 > (cmd->stop_arg * scan_bytes -
+ dmalen0))
+ dmalen1 = cmd->stop_arg * scan_bytes -
+ dmalen0;
}
- if (devpriv->ui_AiFlags & TRIG_WAKE_EOS) {
+ if (cmd->flags & TRIG_WAKE_EOS) {
/* don't we want wake up every scan? */
- if (dmalen0 > (devpriv->ui_AiScanLength * 2)) {
- dmalen0 = devpriv->ui_AiScanLength * 2;
- if (devpriv->ui_AiScanLength & 1)
+ if (dmalen0 > scan_bytes) {
+ dmalen0 = scan_bytes;
+ if (cmd->scan_end_arg & 1)
dmalen0 += 2;
}
- if (dmalen1 > (devpriv->ui_AiScanLength * 2)) {
- dmalen1 = devpriv->ui_AiScanLength * 2;
- if (devpriv->ui_AiScanLength & 1)
+ if (dmalen1 > scan_bytes) {
+ dmalen1 = scan_bytes;
+ if (cmd->scan_end_arg & 1)
dmalen1 -= 2;
if (dmalen1 < 4)
dmalen1 = 4;
}
} else { /* isn't output buff smaller that our DMA buff? */
- if (dmalen0 > (devpriv->ui_AiDataLength))
- dmalen0 = devpriv->ui_AiDataLength;
- if (dmalen1 > (devpriv->ui_AiDataLength))
- dmalen1 = devpriv->ui_AiDataLength;
+ if (dmalen0 > s->async->prealloc_bufsz)
+ dmalen0 = s->async->prealloc_bufsz;
+ if (dmalen1 > s->async->prealloc_bufsz)
+ dmalen1 = s->async->prealloc_bufsz;
}
devpriv->ui_DmaBufferUsesize[0] = dmalen0;
devpriv->ui_DmaBufferUsesize[1] = dmalen1;
/* END JK 07.05.04: Comparison between WIN32 and Linux driver */
}
- if ((devpriv->us_UseDma == APCI3120_DISABLE)
- && !devpriv->b_AiContinuous) {
+ if (devpriv->us_UseDma == APCI3120_DISABLE &&
+ cmd->stop_src == TRIG_COUNT) {
/* set gate 2 to start conversion */
devpriv->us_OutputRegister =
devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER2;
struct comedi_cmd *cmd = &s->async->cmd;
/* loading private structure with cmd structure inputs */
- devpriv->ui_AiFlags = cmd->flags;
devpriv->ui_AiNbrofChannels = cmd->chanlist_len;
- devpriv->ui_AiScanLength = cmd->scan_end_arg;
- devpriv->pui_AiChannelList = cmd->chanlist;
-
- /* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */
- devpriv->ui_AiDataLength = s->async->prealloc_bufsz;
-
- if (cmd->stop_src == TRIG_COUNT)
- devpriv->ui_AiNbrofScans = cmd->stop_arg;
- else
- devpriv->ui_AiNbrofScans = 0;
-
- devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */
- devpriv->ui_AiTimer1 = 0;
- if ((devpriv->ui_AiNbrofScans == 0) || (devpriv->ui_AiNbrofScans == -1))
- devpriv->b_AiContinuous = 1; /* user want neverending analog acquisition */
- /* stopped using cancel */
if (cmd->start_src == TRIG_EXT)
devpriv->b_ExttrigEnable = APCI3120_ENABLE;
else
devpriv->b_ExttrigEnable = APCI3120_DISABLE;
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- /* mode 1 or 3 */
- if (cmd->convert_src == TRIG_TIMER) {
- /* mode 1 */
-
- devpriv->ui_AiTimer0 = cmd->convert_arg; /* timer constant in nano seconds */
- /* return this_board->ai_cmd(1,dev,s); */
- return apci3120_cyclic_ai(1, dev, s);
- }
-
- }
- if ((cmd->scan_begin_src == TRIG_TIMER)
- && (cmd->convert_src == TRIG_TIMER)) {
- /* mode 2 */
- devpriv->ui_AiTimer1 = cmd->scan_begin_arg;
- devpriv->ui_AiTimer0 = cmd->convert_arg; /* variable changed timer2 to timer0 */
- /* return this_board->ai_cmd(2,dev,s); */
+ if (cmd->scan_begin_src == TRIG_FOLLOW)
+ return apci3120_cyclic_ai(1, dev, s);
+ else /* TRIG_TIMER */
return apci3120_cyclic_ai(2, dev, s);
- }
- return -1;
}
/*
unsigned int num_samples)
{
struct addi_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
devpriv->ui_AiActualScan +=
- (s->async->cur_chan + num_samples) / devpriv->ui_AiScanLength;
+ (s->async->cur_chan + num_samples) / cmd->scan_end_arg;
s->async->cur_chan += num_samples;
- s->async->cur_chan %= devpriv->ui_AiScanLength;
+ s->async->cur_chan %= cmd->scan_end_arg;
cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short));
}
struct comedi_device *dev = d;
struct addi_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_cmd *cmd = &s->async->cmd;
unsigned int next_dma_buf, samplesinbuf;
unsigned long low_word, high_word, var;
unsigned int ui_Tmp;
if (samplesinbuf & 1) {
comedi_error(dev, "Odd count of bytes in DMA ring!");
apci3120_cancel(dev, s);
- devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
-
return;
}
samplesinbuf = samplesinbuf >> 1; /* number of received samples */
devpriv->ul_DmaBufferVirtual[devpriv->
ui_DmaActualBuffer], samplesinbuf);
- if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS)) {
+ if (!(cmd->flags & TRIG_WAKE_EOS)) {
s->async->events |= COMEDI_CB_EOS;
comedi_event(dev, s);
}
}
- if (!devpriv->b_AiContinuous)
- if (devpriv->ui_AiActualScan >= devpriv->ui_AiNbrofScans) {
+ if (cmd->stop_src == TRIG_COUNT)
+ if (devpriv->ui_AiActualScan >= cmd->stop_arg) {
/* all data sampled */
apci3120_cancel(dev, s);
- devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
s->async->events |= COMEDI_CB_EOA;
comedi_event(dev, s);
return;
if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { /* enable this in without DMA ??? */
- if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
+ if (devpriv->ai_running) {
ui_Check = 0;
apci3120_interrupt_handle_eos(dev);
devpriv->ui_AiActualScan++;
switch (devpriv->b_Timer2Mode) {
case APCI3120_COUNTER:
-
- devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
devpriv->b_ModeSelectRegister =
devpriv->
b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT;
/* stop timer 0 and timer 1 */
apci3120_cancel(dev, s);
- devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
/* UPDATE-0.7.57->0.7.68comedi_done(dev,s); */
s->async->events |= COMEDI_CB_EOA;
}
if ((int_daq & 0x4) && (devpriv->b_InterruptMode == APCI3120_DMA_MODE)) {
- if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
+ if (devpriv->ai_running) {
/****************************/
/* Clear Timer Write TC int */
unsigned int ui_ConvertTimeBase = 0;
unsigned int ui_DelayTime = 0;
unsigned int ui_DelayTimeBase = 0;
- int i_Triggermode = 0;
- int i_TriggerEdge = 0;
int i_NbrOfChannel = 0;
int i_Cpt = 0;
double d_ConversionTimeForAllChannels = 0.0;
double d_SCANTimeNewUnit = 0.0;
+ unsigned int arg;
/* Step 1 : check if triggers are trivially valid */
/* Step 2b : and mutually compatible */
- if (cmd->start_src == TRIG_EXT) {
- i_TriggerEdge = cmd->start_arg & 0xFFFF;
- i_Triggermode = cmd->start_arg >> 16;
- if (i_TriggerEdge < 1 || i_TriggerEdge > 3) {
- err++;
- printk("\nThe trigger edge selection is in error\n");
- }
- if (i_Triggermode != 2) {
- err++;
- printk("\nThe trigger mode selection is in error\n");
- }
- }
-
if (err) {
apci3200_reset(dev);
return 2;
}
+
+ /* Step 3: check if arguments are trivially valid */
+
+ switch (cmd->start_src) {
+ case TRIG_NOW:
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ break;
+ case TRIG_EXT:
+ /* validate the trigger edge selection */
+ arg = cmd->start_arg & 0xffff;
+ if (arg < 1 || arg > 3) {
+ cmd->start_arg &= ~0xffff;
+ cmd->start_arg |= 1;
+ err |= -EINVAL;
+ }
+ /* validate the trigger mode selection */
+ arg = cmd->start_arg >> 16;
+ if (arg != 2) {
+ cmd->start_arg &= ~(0xffff << 16);
+ cmd->start_arg |= (2 << 16);
+ err |= -EINVAL;
+ }
+ break;
+ }
+
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
/* i_FirstChannel=cmd->chanlist[0]; */
s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
/* i_LastChannel=cmd->chanlist[1]; */
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
s->range_table = &range_digital;
s->insn_config = apci1032_cos_insn_config;
s->insn_bits = apci1032_cos_insn_bits;
+ s->len_chanlist = 1;
s->do_cmdtest = apci1032_cos_cmdtest;
s->do_cmd = apci1032_cos_cmd;
s->cancel = apci1032_cos_cancel;
module_comedi_pci_driver(apci1032_driver, apci1032_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("ADDI-DATA APCI-1032, 32 channel DI boards");
MODULE_LICENSE("GPL");
module_comedi_pci_driver(apci1500_driver, apci1500_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("ADDI-DATA APCI-1500, 16 channel DI / 16 channel DO boards");
MODULE_LICENSE("GPL");
#include "../comedidev.h"
#include "comedi_fc.h"
-#include "amcc_s5933.h"
#include "addi-data/addi_common.h"
-#include "addi-data/addi_eeprom.c"
#include "addi-data/hwdrv_apci1564.c"
-#include "addi-data/addi_common.c"
static const struct addi_board apci1564_boardtypes[] = {
{
.pc_DriverName = "apci1564",
- .i_IorangeBase1 = APCI1564_ADDRESS_RANGE,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_93C76,
.i_NbrDiChannel = 32,
.i_NbrDoChannel = 32,
.i_DoMaxdata = 0xffffffff,
.i_Timer = 1,
.interrupt = apci1564_interrupt,
.reset = apci1564_reset,
- .di_config = apci1564_di_config,
- .di_bits = apci1564_di_insn_bits,
.do_config = apci1564_do_config,
.do_bits = apci1564_do_insn_bits,
.do_read = apci1564_do_read,
},
};
+static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ const struct addi_board *this_board = comedi_board(dev);
+
+ this_board->interrupt(irq, d);
+ return IRQ_RETVAL(1);
+}
+
+static int i_ADDI_Reset(struct comedi_device *dev)
+{
+ const struct addi_board *this_board = comedi_board(dev);
+
+ this_board->reset(dev);
+ return 0;
+}
+
static int apci1564_auto_attach(struct comedi_device *dev,
- unsigned long context)
+ unsigned long context_unused)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv;
+ struct comedi_subdevice *s;
+ int ret, n_subdevices;
+
+ dev->board_name = this_board->pc_DriverName;
+
+ devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+ if (!devpriv)
+ return -ENOMEM;
+
+ ret = comedi_pci_enable(dev);
+ if (ret)
+ return ret;
+
+ dev->iobase = pci_resource_start(pcidev, 1);
+ devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
+
+ if (pcidev->irq > 0) {
+ ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (ret == 0)
+ dev->irq = pcidev->irq;
+ }
+
+ n_subdevices = 7;
+ ret = comedi_alloc_subdevices(dev, n_subdevices);
+ if (ret)
+ return ret;
+
+ /* Allocate and Initialise AI Subdevice Structures */
+ s = &dev->subdevices[0];
+ s->type = COMEDI_SUBD_UNUSED;
+
+ /* Allocate and Initialise AO Subdevice Structures */
+ s = &dev->subdevices[1];
+ s->type = COMEDI_SUBD_UNUSED;
+
+ /* Allocate and Initialise DI Subdevice Structures */
+ s = &dev->subdevices[2];
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 32;
+ s->maxdata = 1;
+ s->len_chanlist = 32;
+ s->range_table = &range_digital;
+ s->insn_config = apci1564_di_config;
+ s->insn_bits = apci1564_di_insn_bits;
+
+ /* Allocate and Initialise DO Subdevice Structures */
+ s = &dev->subdevices[3];
+ if (this_board->i_NbrDoChannel) {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->i_NbrDoChannel;
+ s->maxdata = this_board->i_DoMaxdata;
+ s->len_chanlist = this_board->i_NbrDoChannel;
+ s->range_table = &range_digital;
+
+ /* insn_config - for digital output memory */
+ s->insn_config = this_board->do_config;
+ s->insn_write = this_board->do_write;
+ s->insn_bits = this_board->do_bits;
+ s->insn_read = this_board->do_read;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* Allocate and Initialise Timer Subdevice Structures */
+ s = &dev->subdevices[4];
+ if (this_board->i_Timer) {
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 1;
+ s->maxdata = 0;
+ s->len_chanlist = 1;
+ s->range_table = &range_digital;
+
+ s->insn_write = this_board->timer_write;
+ s->insn_read = this_board->timer_read;
+ s->insn_config = this_board->timer_config;
+ s->insn_bits = this_board->timer_bits;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* Allocate and Initialise TTL */
+ s = &dev->subdevices[5];
+ s->type = COMEDI_SUBD_UNUSED;
+
+ /* EEPROM */
+ s = &dev->subdevices[6];
+ s->type = COMEDI_SUBD_UNUSED;
+
+ i_ADDI_Reset(dev);
+ return 0;
+}
+
+static void apci1564_detach(struct comedi_device *dev)
{
- dev->board_ptr = &apci1564_boardtypes[0];
+ struct addi_private *devpriv = dev->private;
- return addi_auto_attach(dev, context);
+ if (devpriv) {
+ if (dev->iobase)
+ i_ADDI_Reset(dev);
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ }
+ comedi_pci_disable(dev);
}
static struct comedi_driver apci1564_driver = {
.driver_name = "addi_apci_1564",
.module = THIS_MODULE,
.auto_attach = apci1564_auto_attach,
- .detach = i_ADDI_Detach,
+ .detach = apci1564_detach,
};
static int apci1564_pci_probe(struct pci_dev *dev,
module_comedi_pci_driver(apci1564_driver, apci1564_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("ADDI-DATA APCI-1564, 32 channel DI / 32 channel DO boards");
MODULE_LICENSE("GPL");
{
struct comedi_device *dev = d;
struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_cmd *cmd = &s->async->cmd;
struct apci2032_int_private *subpriv;
unsigned int val;
bool do_event = false;
*/
if (subpriv->active && (val & subpriv->enabled_isns) != 0) {
- unsigned short bits;
- unsigned int n, len;
- unsigned int *chanlist;
+ unsigned short bits = 0;
+ int i;
/* Bits in scan data correspond to indices in channel list. */
- bits = 0;
- len = s->async->cmd.chanlist_len;
- chanlist = &s->async->cmd.chanlist[0];
- for (n = 0; n < len; n++)
- if ((val & (1U << CR_CHAN(chanlist[n]))) != 0)
- bits |= 1U << n;
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+
+ if (val & (1 << chan))
+ bits |= (1 << i);
+ }
if (comedi_buf_put(s->async, bits)) {
s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
- if (s->async->cmd.stop_src == TRIG_COUNT &&
+ if (cmd->stop_src == TRIG_COUNT &&
subpriv->stop_count > 0) {
subpriv->stop_count--;
if (subpriv->stop_count == 0) {
module_comedi_pci_driver(apci2032_driver, apci2032_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("ADDI-DATA APCI-2032, 32 channel DO boards");
MODULE_LICENSE("GPL");
module_comedi_pci_driver(apci3120_driver, apci3120_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("ADDI-DATA APCI-3120, Analog input board");
MODULE_LICENSE("GPL");
/* step 4: fix up any arguments */
- /*
- * FIXME: The hardware supports multiple scan modes but the original
- * addi-data driver only supported reading a single channel with
- * interrupts. Need a proper datasheet to fix this.
- *
- * The following scan modes are supported by the hardware:
- * 1) Single software scan
- * 2) Single hardware triggered scan
- * 3) Continuous software scan
- * 4) Continuous software scan with timer delay
- * 5) Continuous hardware triggered scan
- * 6) Continuous hardware triggered scan with timer delay
- *
- * For now, limit the chanlist to a single channel.
- */
- if (cmd->chanlist_len > 1) {
- cmd->chanlist_len = 1;
- err |= -EINVAL;
- }
-
tmp = cmd->convert_arg;
err |= apci3xxx_ai_ns_to_timer(dev, &cmd->convert_arg,
cmd->flags & TRIG_ROUND_MASK);
if (chan < 16)
return -EINVAL;
else
- /* changing any channel in port 2 changes the entire port */
+ /* changing any channel in port 2 */
+ /* changes the entire port */
mask = 0xff0000;
}
s->subdev_flags = SDF_READABLE | board->ai_subdev_flags;
s->n_chan = board->ai_n_chan;
s->maxdata = board->ai_maxdata;
- s->len_chanlist = s->n_chan;
s->range_table = &apci3xxx_ai_range;
s->insn_read = apci3xxx_ai_insn_read;
if (dev->irq) {
+ /*
+ * FIXME: The hardware supports multiple scan modes
+ * but the original addi-data driver only supported
+ * reading a single channel with interrupts. Need a
+ * proper datasheet to fix this.
+ *
+ * The following scan modes are supported by the
+ * hardware:
+ * 1) Single software scan
+ * 2) Single hardware triggered scan
+ * 3) Continuous software scan
+ * 4) Continuous software scan with timer delay
+ * 5) Continuous hardware triggered scan
+ * 6) Continuous hardware triggered scan with timer
+ * delay
+ *
+ * For now, limit the chanlist to a single channel.
+ */
dev->read_subdev = s;
s->subdev_flags |= SDF_CMD_READ;
+ s->len_chanlist = 1;
s->do_cmdtest = apci3xxx_ai_cmdtest;
s->do_cmd = apci3xxx_ai_cmd;
s->cancel = apci3xxx_ai_cancel;
return 0;
}
+static int pci9111_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
+ unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
+ int i;
+
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+ unsigned int range = CR_RANGE(cmd->chanlist[i]);
+ unsigned int aref = CR_AREF(cmd->chanlist[i]);
+
+ if (chan != i) {
+ dev_dbg(dev->class_dev,
+ "entries in chanlist must be consecutive channels,counting upwards from 0\n");
+ return -EINVAL;
+ }
+
+ if (range != range0) {
+ dev_dbg(dev->class_dev,
+ "entries in chanlist must all have the same gain\n");
+ return -EINVAL;
+ }
+
+ if (aref != aref0) {
+ dev_dbg(dev->class_dev,
+ "entries in chanlist must all have the same reference\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int pci9111_ai_do_cmd_test(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
struct pci9111_private_data *dev_private = dev->private;
- int tmp;
- int error = 0;
- int range, reference;
- int i;
+ int err = 0;
+ unsigned int arg;
/* Step 1 : check if triggers are trivially valid */
- error |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
- error |= cfc_check_trigger_src(&cmd->scan_begin_src,
+ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
+ err |= cfc_check_trigger_src(&cmd->scan_begin_src,
TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
- error |= cfc_check_trigger_src(&cmd->convert_src,
+ err |= cfc_check_trigger_src(&cmd->convert_src,
TRIG_TIMER | TRIG_EXT);
- error |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- error |= cfc_check_trigger_src(&cmd->stop_src,
+ err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+ err |= cfc_check_trigger_src(&cmd->stop_src,
TRIG_COUNT | TRIG_NONE);
- if (error)
+ if (err)
return 1;
/* Step 2a : make sure trigger sources are unique */
- error |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
- error |= cfc_check_trigger_is_unique(cmd->convert_src);
- error |= cfc_check_trigger_is_unique(cmd->stop_src);
+ err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
+ err |= cfc_check_trigger_is_unique(cmd->convert_src);
+ err |= cfc_check_trigger_is_unique(cmd->stop_src);
/* Step 2b : and mutually compatible */
- if ((cmd->convert_src == TRIG_TIMER) &&
- !((cmd->scan_begin_src == TRIG_TIMER) ||
- (cmd->scan_begin_src == TRIG_FOLLOW)))
- error |= -EINVAL;
- if ((cmd->convert_src == TRIG_EXT) &&
- !((cmd->scan_begin_src == TRIG_EXT) ||
- (cmd->scan_begin_src == TRIG_FOLLOW)))
- error |= -EINVAL;
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ if (cmd->scan_begin_src != cmd->convert_src)
+ err |= -EINVAL;
+ }
- if (error)
+ if (err)
return 2;
/* Step 3: check if arguments are trivially valid */
- error |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
if (cmd->convert_src == TRIG_TIMER)
- error |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+ err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
PCI9111_AI_ACQUISITION_PERIOD_MIN_NS);
else /* TRIG_EXT */
- error |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
if (cmd->scan_begin_src == TRIG_TIMER)
- error |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
+ err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
PCI9111_AI_ACQUISITION_PERIOD_MIN_NS);
else /* TRIG_FOLLOW || TRIG_EXT */
- error |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- error |= cfc_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
if (cmd->stop_src == TRIG_COUNT)
- error |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+ err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
else /* TRIG_NONE */
- error |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
- if (error)
+ if (err)
return 3;
- /* Step 4 : fix up any arguments */
+ /* Step 4: fix up any arguments */
if (cmd->convert_src == TRIG_TIMER) {
- tmp = cmd->convert_arg;
+ arg = cmd->convert_arg;
i8253_cascade_ns_to_timer(I8254_OSC_BASE_2MHZ,
&dev_private->div1,
&dev_private->div2,
&cmd->convert_arg, cmd->flags);
- if (tmp != cmd->convert_arg)
- error++;
+ if (cmd->convert_arg != arg)
+ err |= -EINVAL;
}
- /* There's only one timer on this card, so the scan_begin timer must */
- /* be a multiple of chanlist_len*convert_arg */
+ /*
+ * There's only one timer on this card, so the scan_begin timer
+ * must be a multiple of chanlist_len*convert_arg
+ */
if (cmd->scan_begin_src == TRIG_TIMER) {
+ arg = cmd->chanlist_len * cmd->convert_arg;
- unsigned int scan_begin_min;
- unsigned int scan_begin_arg;
- unsigned int scan_factor;
-
- scan_begin_min = cmd->chanlist_len * cmd->convert_arg;
+ if (arg < cmd->scan_begin_arg)
+ arg *= (cmd->scan_begin_arg / arg);
- if (cmd->scan_begin_arg != scan_begin_min) {
- if (scan_begin_min < cmd->scan_begin_arg) {
- scan_factor =
- cmd->scan_begin_arg / scan_begin_min;
- scan_begin_arg = scan_factor * scan_begin_min;
- if (cmd->scan_begin_arg != scan_begin_arg) {
- cmd->scan_begin_arg = scan_begin_arg;
- error++;
- }
- } else {
- cmd->scan_begin_arg = scan_begin_min;
- error++;
- }
+ if (cmd->scan_begin_arg != arg) {
+ cmd->scan_begin_arg = arg;
+ err |= -EINVAL;
}
}
- if (error)
+ if (err)
return 4;
- /* Step 5 : check channel list */
-
- if (cmd->chanlist) {
-
- range = CR_RANGE(cmd->chanlist[0]);
- reference = CR_AREF(cmd->chanlist[0]);
-
- if (cmd->chanlist_len > 1) {
- for (i = 0; i < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i]) != i) {
- comedi_error(dev,
- "entries in chanlist must be consecutive "
- "channels,counting upwards from 0\n");
- error++;
- }
- if (CR_RANGE(cmd->chanlist[i]) != range) {
- comedi_error(dev,
- "entries in chanlist must all have the same gain\n");
- error++;
- }
- if (CR_AREF(cmd->chanlist[i]) != reference) {
- comedi_error(dev,
- "entries in chanlist must all have the same reference\n");
- error++;
- }
- }
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= pci9111_ai_check_chanlist(dev, s, cmd);
- if (error)
+ if (err)
return 5;
return 0;
* correct channel number on every 12 bit sample
*/
-#define IORANGE_9118 64 /* I hope */
+#define IORANGE_9118 64 /* I hope */
#define PCI9118_CHANLEN 255 /*
* len of chanlist, some source say 256,
* but reality looks like 255 :-(
* users(0-AI, 1-AO, 2-DI, 3-DO)
*/
unsigned int cnt0_divisor; /* actual CNT0 divisor */
- void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *,
+ void (*int_ai_func)(struct comedi_device *, struct comedi_subdevice *,
unsigned short,
unsigned int,
unsigned short); /*
*/
unsigned int ai_maskerr; /* which warning was printed */
unsigned int ai_maskharderr; /* on which error bits stops */
- unsigned int ai_inttrig_start; /* TRIG_INT for start */
};
static int check_channel_list(struct comedi_device *dev,
move_block_from_dma(dev, s,
devpriv->dmabuf_virt[devpriv->dma_actbuf],
samplesinbuf);
- m = m - sampls; /* m= how many samples was transferred */
+ m = m - sampls; /* m=how many samples was transferred */
}
if (!devpriv->ai_neverending) {
}
static int pci9118_ai_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int trignum)
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
struct pci9118_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
- if (trignum != devpriv->ai_inttrig_start)
+ if (trig_num != cmd->start_arg)
return -EINVAL;
devpriv->ai12_startstop &= ~START_AI_INT;
/* Step 3: check if arguments are trivially valid */
- if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
+ switch (cmd->start_src) {
+ case TRIG_NOW:
+ case TRIG_EXT:
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ break;
+ case TRIG_INT:
+ /* start_arg is the internal trigger (any value) */
+ break;
+ }
if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= cfc_check_trigger_arg_max(&cmd->chanlist_len,
- this_board->n_aichanlist);
err |= cfc_check_trigger_arg_min(&cmd->scan_end_arg,
cmd->chanlist_len);
}
if (cmd->start_src == TRIG_INT) {
devpriv->ai12_startstop |= START_AI_INT;
- devpriv->ai_inttrig_start = cmd->start_arg;
s->async->inttrig = pci9118_ai_inttrig;
}
#if 0
#include "8253.h"
#include "amcc_s5933.h"
-#define PCI171x_PARANOIDCHECK /* if defined, then is used code which control
- * correct channel number on every 12 bit
- * sample */
-
/* hardware types of the cards */
#define TYPE_PCI171X 0
#define TYPE_PCI1713 2
#define PCI171x_DAREF 14 /* W: D/A reference control */
#define PCI171x_DI 16 /* R: digi inputs */
#define PCI171x_DO 16 /* R: digi inputs */
+
+#define PCI171X_TIMER_BASE 0x18
+
#define PCI171x_CNT0 24 /* R/W: 8254 counter 0 */
#define PCI171x_CNT1 26 /* R/W: 8254 counter 1 */
#define PCI171x_CNT2 28 /* R/W: 8254 counter 2 */
};
struct pci1710_private {
- char neverending_ai; /* we do unlimited AI */
unsigned int CntrlReg; /* Control register */
- unsigned int i8254_osc_base; /* frequence of onboard oscilator */
- unsigned int ai_do; /* what do AI? 0=nothing, 1 to 4 mode */
unsigned int ai_act_scan; /* how many scans we finished */
- unsigned int ai_act_chan; /* actual position in actual scan */
- unsigned int ai_buf_ptr; /* data buffer ptr in samples */
- unsigned char ai_eos; /* 1=EOS wake up */
unsigned char ai_et;
unsigned int ai_et_CntrlReg;
unsigned int ai_et_MuxVal;
- unsigned int ai_et_div1, ai_et_div2;
+ unsigned int next_divisor1;
+ unsigned int next_divisor2;
+ unsigned int divisor1;
+ unsigned int divisor2;
unsigned int act_chanlist[32]; /* list of scanned channel */
- unsigned char act_chanlist_len; /* len of scanlist */
- unsigned char act_chanlist_pos; /* actual position in MUX list */
+ unsigned char saved_seglen; /* len of the non-repeating chanlist */
unsigned char da_ranges; /* copy of D/A outpit range register */
- unsigned int ai_scans; /* len of scanlist */
- unsigned int ai_n_chan; /* how many channels is measured */
- unsigned int *ai_chanlist; /* actaul chanlist */
- unsigned int ai_flags; /* flaglist */
- unsigned int ai_data_len; /* len of data buffer */
- unsigned int ai_timer1; /* timers */
- unsigned int ai_timer2;
unsigned short ao_data[4]; /* data output buffer */
unsigned int cnt0_write_wait; /* after a write, wait for update of the
* internal state */
0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f
};
-/*
-==============================================================================
- Check if channel list from user is built correctly
- If it's ok, then program scan/gain logic.
- This works for all cards.
-*/
-static int check_channel_list(struct comedi_device *dev,
+static int pci171x_ai_dropout(struct comedi_device *dev,
struct comedi_subdevice *s,
- unsigned int *chanlist, unsigned int n_chan)
+ unsigned int chan,
+ unsigned int val)
+{
+ const struct boardtype *board = comedi_board(dev);
+ struct pci1710_private *devpriv = dev->private;
+
+ if (board->cardtype != TYPE_PCI1713) {
+ if ((val & 0xf000) != devpriv->act_chanlist[chan]) {
+ dev_err(dev->class_dev,
+ "A/D data droput: received from channel %d, expected %d\n",
+ (val >> 12) & 0xf,
+ (devpriv->act_chanlist[chan] >> 12) & 0xf);
+ return -ENODATA;
+ }
+ }
+ return 0;
+}
+
+static int pci171x_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
+ struct pci1710_private *devpriv = dev->private;
+ unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
+ unsigned int last_aref = CR_AREF(cmd->chanlist[0]);
+ unsigned int next_chan = (chan0 + 1) % s->n_chan;
unsigned int chansegment[32];
- unsigned int i, nowmustbechan, seglen, segpos;
+ unsigned int seglen;
+ int i;
- /* correct channel and range number check itself comedi/range.c */
- if (n_chan < 1) {
- comedi_error(dev, "range/channel list is empty!");
+ if (cmd->chanlist_len == 1) {
+ devpriv->saved_seglen = cmd->chanlist_len;
return 0;
}
- if (n_chan == 1)
- return 1; /* seglen=1 */
+ /* first channel is always ok */
+ chansegment[0] = cmd->chanlist[0];
- chansegment[0] = chanlist[0]; /* first channel is every time ok */
- for (i = 1, seglen = 1; i < n_chan; i++, seglen++) {
- if (chanlist[0] == chanlist[i])
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+ unsigned int aref = CR_AREF(cmd->chanlist[i]);
+
+ if (cmd->chanlist[0] == cmd->chanlist[i])
break; /* we detected a loop, stop */
- if ((CR_CHAN(chanlist[i]) & 1) &&
- (CR_AREF(chanlist[i]) == AREF_DIFF)) {
- comedi_error(dev, "Odd channel cannot be differential input!\n");
- return 0;
+
+ if (aref == AREF_DIFF && (chan & 1)) {
+ dev_err(dev->class_dev,
+ "Odd channel cannot be differential input!\n");
+ return -EINVAL;
}
- nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
- if (CR_AREF(chansegment[i - 1]) == AREF_DIFF)
- nowmustbechan = (nowmustbechan + 1) % s->n_chan;
- if (nowmustbechan != CR_CHAN(chanlist[i])) {
- printk("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
- i, CR_CHAN(chanlist[i]), nowmustbechan,
- CR_CHAN(chanlist[0]));
- return 0;
+
+ if (last_aref == AREF_DIFF)
+ next_chan = (next_chan + 1) % s->n_chan;
+ if (chan != next_chan) {
+ dev_err(dev->class_dev,
+ "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
+ i, chan, next_chan, chan0);
+ return -EINVAL;
}
- chansegment[i] = chanlist[i]; /* next correct channel in list */
- }
- for (i = 0, segpos = 0; i < n_chan; i++) {
- if (chanlist[i] != chansegment[i % seglen]) {
- printk("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
- i, CR_CHAN(chansegment[i]),
- CR_RANGE(chansegment[i]),
- CR_AREF(chansegment[i]),
- CR_CHAN(chanlist[i % seglen]),
- CR_RANGE(chanlist[i % seglen]),
- CR_AREF(chansegment[i % seglen]));
- return 0;
+ /* next correct channel in list */
+ chansegment[i] = cmd->chanlist[i];
+ last_aref = aref;
+ }
+ seglen = i;
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ if (cmd->chanlist[i] != chansegment[i % seglen]) {
+ dev_err(dev->class_dev,
+ "bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+ i, CR_CHAN(chansegment[i]),
+ CR_RANGE(chansegment[i]),
+ CR_AREF(chansegment[i]),
+ CR_CHAN(cmd->chanlist[i % seglen]),
+ CR_RANGE(cmd->chanlist[i % seglen]),
+ CR_AREF(chansegment[i % seglen]));
+ return -EINVAL;
}
}
- return seglen;
+ devpriv->saved_seglen = seglen;
+
+ return 0;
}
static void setup_channel_list(struct comedi_device *dev,
struct pci1710_private *devpriv = dev->private;
unsigned int i, range, chanprog;
- devpriv->act_chanlist_len = seglen;
- devpriv->act_chanlist_pos = 0;
-
for (i = 0; i < seglen; i++) { /* store range list to card */
chanprog = muxonechan[CR_CHAN(chanlist[i])];
outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */
if (CR_AREF(chanlist[i]) == AREF_DIFF)
range |= 0x0020;
outw(range, dev->iobase + PCI171x_RANGE); /* select gain */
-#ifdef PCI171x_PARANOIDCHECK
devpriv->act_chanlist[i] =
(CR_CHAN(chanlist[i]) << 12) & 0xf000;
-#endif
}
-#ifdef PCI171x_PARANOIDCHECK
for ( ; i < n_chan; i++) { /* store remainder of channel list */
devpriv->act_chanlist[i] =
(CR_CHAN(chanlist[i]) << 12) & 0xf000;
}
-#endif
devpriv->ai_et_MuxVal =
CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
struct comedi_insn *insn, unsigned int *data)
{
struct pci1710_private *devpriv = dev->private;
- int ret;
- int n;
-#ifdef PCI171x_PARANOIDCHECK
- const struct boardtype *this_board = comedi_board(dev);
- unsigned int idata;
-#endif
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int ret = 0;
+ int i;
devpriv->CntrlReg &= Control_CNT0;
devpriv->CntrlReg |= Control_SW; /* set software trigger */
setup_channel_list(dev, s, &insn->chanspec, 1, 1);
- for (n = 0; n < insn->n; n++) {
+ for (i = 0; i < insn->n; i++) {
+ unsigned int val;
+
outw(0, dev->iobase + PCI171x_SOFTTRG); /* start conversion */
ret = comedi_timeout(dev, s, insn, pci171x_ai_eoc, 0);
- if (ret) {
- outb(0, dev->iobase + PCI171x_CLRFIFO);
- outb(0, dev->iobase + PCI171x_CLRINT);
- return ret;
- }
+ if (ret)
+ break;
-#ifdef PCI171x_PARANOIDCHECK
- idata = inw(dev->iobase + PCI171x_AD_DATA);
- if (this_board->cardtype != TYPE_PCI1713)
- if ((idata & 0xf000) != devpriv->act_chanlist[0]) {
- comedi_error(dev, "A/D insn data droput!");
- return -ETIME;
- }
- data[n] = idata & 0x0fff;
-#else
- data[n] = inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff;
-#endif
+ val = inw(dev->iobase + PCI171x_AD_DATA);
+ ret = pci171x_ai_dropout(dev, s, chan, val);
+ if (ret)
+ break;
+ data[i] = val & s->maxdata;
}
outb(0, dev->iobase + PCI171x_CLRFIFO);
outb(0, dev->iobase + PCI171x_CLRINT);
- return n;
+ return ret ? ret : insn->n;
}
/*
return insn->n;
}
-/*
-==============================================================================
-*/
-static void start_pacer(struct comedi_device *dev, int mode,
- unsigned int divisor1, unsigned int divisor2)
+static void pci171x_start_pacer(struct comedi_device *dev,
+ bool load_counters)
{
- outw(0xb4, dev->iobase + PCI171x_CNTCTRL);
- outw(0x74, dev->iobase + PCI171x_CNTCTRL);
-
- if (mode == 1) {
- outw(divisor2 & 0xff, dev->iobase + PCI171x_CNT2);
- outw((divisor2 >> 8) & 0xff, dev->iobase + PCI171x_CNT2);
- outw(divisor1 & 0xff, dev->iobase + PCI171x_CNT1);
- outw((divisor1 >> 8) & 0xff, dev->iobase + PCI171x_CNT1);
+ struct pci1710_private *devpriv = dev->private;
+ unsigned long timer_base = dev->iobase + PCI171X_TIMER_BASE;
+
+ i8254_set_mode(timer_base, 1, 2, I8254_MODE2 | I8254_BINARY);
+ i8254_set_mode(timer_base, 1, 1, I8254_MODE2 | I8254_BINARY);
+
+ if (load_counters) {
+ i8254_write(timer_base, 1, 2, devpriv->divisor2);
+ i8254_write(timer_base, 1, 1, devpriv->divisor1);
}
}
devpriv->CntrlReg |= Control_SW;
outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /* reset any operations */
- start_pacer(dev, -1, 0, 0);
+ pci171x_start_pacer(dev, false);
outb(0, dev->iobase + PCI171x_CLRFIFO);
outb(0, dev->iobase + PCI171x_CLRINT);
break;
}
- devpriv->ai_do = 0;
devpriv->ai_act_scan = 0;
s->async->cur_chan = 0;
- devpriv->ai_buf_ptr = 0;
- devpriv->neverending_ai = 0;
return 0;
}
-/*
-==============================================================================
-*/
-static void interrupt_pci1710_every_sample(void *d)
+static void pci1710_handle_every_sample(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
- struct comedi_device *dev = d;
struct pci1710_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- int m;
-#ifdef PCI171x_PARANOIDCHECK
- const struct boardtype *this_board = comedi_board(dev);
- unsigned short sampl;
-#endif
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int status;
+ unsigned int val;
+ int ret;
- m = inw(dev->iobase + PCI171x_STATUS);
- if (m & Status_FE) {
- dev_dbg(dev->class_dev, "A/D FIFO empty (%4x)\n", m);
+ status = inw(dev->iobase + PCI171x_STATUS);
+ if (status & Status_FE) {
+ dev_dbg(dev->class_dev, "A/D FIFO empty (%4x)\n", status);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
cfc_handle_events(dev, s);
return;
}
- if (m & Status_FF) {
+ if (status & Status_FF) {
dev_dbg(dev->class_dev,
- "A/D FIFO Full status (Fatal Error!) (%4x)\n", m);
+ "A/D FIFO Full status (Fatal Error!) (%4x)\n", status);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
cfc_handle_events(dev, s);
return;
outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */
for (; !(inw(dev->iobase + PCI171x_STATUS) & Status_FE);) {
-#ifdef PCI171x_PARANOIDCHECK
- sampl = inw(dev->iobase + PCI171x_AD_DATA);
- if (this_board->cardtype != TYPE_PCI1713)
- if ((sampl & 0xf000) !=
- devpriv->act_chanlist[s->async->cur_chan]) {
- printk
- ("comedi: A/D data dropout: received data from channel %d, expected %d!\n",
- (sampl & 0xf000) >> 12,
- (devpriv->
- act_chanlist[s->
- async->cur_chan] & 0xf000) >>
- 12);
- s->async->events |=
- COMEDI_CB_EOA | COMEDI_CB_ERROR;
- cfc_handle_events(dev, s);
- return;
- }
- comedi_buf_put(s->async, sampl & 0x0fff);
-#else
- comedi_buf_put(s->async,
- inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
-#endif
- ++s->async->cur_chan;
+ val = inw(dev->iobase + PCI171x_AD_DATA);
+ ret = pci171x_ai_dropout(dev, s, s->async->cur_chan, val);
+ if (ret) {
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ break;
+ }
- if (s->async->cur_chan >= devpriv->ai_n_chan)
+ comedi_buf_put(s->async, val & s->maxdata);
+
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= cmd->chanlist_len)
s->async->cur_chan = 0;
if (s->async->cur_chan == 0) { /* one scan done */
devpriv->ai_act_scan++;
- if ((!devpriv->neverending_ai) &&
- (devpriv->ai_act_scan >= devpriv->ai_scans)) {
+ if (cmd->stop_src == TRIG_COUNT &&
+ devpriv->ai_act_scan >= cmd->stop_arg) {
/* all data sampled */
s->async->events |= COMEDI_CB_EOA;
- cfc_handle_events(dev, s);
- return;
+ break;
}
}
}
struct comedi_subdevice *s, int n, int turn)
{
struct pci1710_private *devpriv = dev->private;
- int i, j;
-#ifdef PCI171x_PARANOIDCHECK
- const struct boardtype *this_board = comedi_board(dev);
- unsigned short sampl;
-#endif
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int val;
+ int ret;
+ int i;
- j = s->async->cur_chan;
for (i = 0; i < n; i++) {
-#ifdef PCI171x_PARANOIDCHECK
- sampl = inw(dev->iobase + PCI171x_AD_DATA);
- if (this_board->cardtype != TYPE_PCI1713)
- if ((sampl & 0xf000) != devpriv->act_chanlist[j]) {
- dev_dbg(dev->class_dev,
- "A/D FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n",
- (sampl & 0xf000) >> 12,
- (devpriv->act_chanlist[j] & 0xf000) >> 12,
- i, j, devpriv->ai_act_scan, n, turn,
- sampl);
- s->async->events |=
- COMEDI_CB_EOA | COMEDI_CB_ERROR;
- cfc_handle_events(dev, s);
- return 1;
- }
- comedi_buf_put(s->async, sampl & 0x0fff);
-#else
- comedi_buf_put(s->async,
- inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
-#endif
- j++;
- if (j >= devpriv->ai_n_chan) {
- j = 0;
+ val = inw(dev->iobase + PCI171x_AD_DATA);
+
+ ret = pci171x_ai_dropout(dev, s, s->async->cur_chan, val);
+ if (ret) {
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ return ret;
+ }
+
+ comedi_buf_put(s->async, val & s->maxdata);
+
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= cmd->chanlist_len) {
+ s->async->cur_chan = 0;
devpriv->ai_act_scan++;
}
}
- s->async->cur_chan = j;
return 0;
}
-/*
-==============================================================================
-*/
-static void interrupt_pci1710_half_fifo(void *d)
+static void pci1710_handle_fifo(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
- struct comedi_device *dev = d;
const struct boardtype *this_board = comedi_board(dev);
struct pci1710_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_cmd *cmd = &s->async->cmd;
int m, samplesinbuf;
m = inw(dev->iobase + PCI171x_STATUS);
}
samplesinbuf = this_board->fifo_half_size;
- if (samplesinbuf * sizeof(short) >= devpriv->ai_data_len) {
- m = devpriv->ai_data_len / sizeof(short);
+ if (samplesinbuf * sizeof(short) >= s->async->prealloc_bufsz) {
+ m = s->async->prealloc_bufsz / sizeof(short);
if (move_block_from_fifo(dev, s, m, 0))
return;
samplesinbuf -= m;
return;
}
- if (!devpriv->neverending_ai)
- if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data
- sampled */
- s->async->events |= COMEDI_CB_EOA;
- cfc_handle_events(dev, s);
- return;
- }
+ if (cmd->stop_src == TRIG_COUNT &&
+ devpriv->ai_act_scan >= cmd->stop_arg) {
+ /* all data sampled */
+ s->async->events |= COMEDI_CB_EOA;
+ cfc_handle_events(dev, s);
+ return;
+ }
outb(0, dev->iobase + PCI171x_CLRINT); /* clear our INT request */
cfc_handle_events(dev, s);
{
struct comedi_device *dev = d;
struct pci1710_private *devpriv = dev->private;
+ struct comedi_subdevice *s;
+ struct comedi_cmd *cmd;
if (!dev->attached) /* is device attached? */
return IRQ_NONE; /* no, exit */
+
+ s = dev->read_subdev;
+ cmd = &s->async->cmd;
+
/* is this interrupt from our board? */
if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ))
return IRQ_NONE; /* no, exit */
outb(0, dev->iobase + PCI171x_CLRINT);
outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX);
outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
- /* start pacer */
- start_pacer(dev, 1, devpriv->ai_et_div1, devpriv->ai_et_div2);
+ pci171x_start_pacer(dev, true);
return IRQ_HANDLED;
}
- if (devpriv->ai_eos) { /* We use FIFO half full INT or not? */
- interrupt_pci1710_every_sample(d);
- } else {
- interrupt_pci1710_half_fifo(d);
- }
+
+ if (cmd->flags & TRIG_WAKE_EOS)
+ pci1710_handle_every_sample(dev, s);
+ else
+ pci1710_handle_fifo(dev, s);
+
return IRQ_HANDLED;
}
-/*
-==============================================================================
-*/
-static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
- struct comedi_subdevice *s)
+static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- const struct boardtype *this_board = comedi_board(dev);
struct pci1710_private *devpriv = dev->private;
- unsigned int divisor1 = 0, divisor2 = 0;
- unsigned int seglen;
+ struct comedi_cmd *cmd = &s->async->cmd;
- start_pacer(dev, -1, 0, 0); /* stop pacer */
+ pci171x_start_pacer(dev, false);
- seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
- devpriv->ai_n_chan);
- if (seglen < 1)
- return -EINVAL;
- setup_channel_list(dev, s, devpriv->ai_chanlist,
- devpriv->ai_n_chan, seglen);
+ setup_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len,
+ devpriv->saved_seglen);
outb(0, dev->iobase + PCI171x_CLRFIFO);
outb(0, dev->iobase + PCI171x_CLRINT);
- devpriv->ai_do = mode;
-
devpriv->ai_act_scan = 0;
s->async->cur_chan = 0;
- devpriv->ai_buf_ptr = 0;
- devpriv->neverending_ai = 0;
devpriv->CntrlReg &= Control_CNT0;
- /* don't we want wake up every scan? devpriv->ai_eos=1; */
- if ((devpriv->ai_flags & TRIG_WAKE_EOS)) {
- devpriv->ai_eos = 1;
- } else {
+ if ((cmd->flags & TRIG_WAKE_EOS) == 0)
devpriv->CntrlReg |= Control_ONEFH;
- devpriv->ai_eos = 0;
- }
- if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1))
- devpriv->neverending_ai = 1;
- /* well, user want neverending */
- else
- devpriv->neverending_ai = 0;
+ devpriv->divisor1 = devpriv->next_divisor1;
+ devpriv->divisor2 = devpriv->next_divisor2;
- switch (mode) {
- case 1:
- case 2:
- if (devpriv->ai_timer1 < this_board->ai_ns_min)
- devpriv->ai_timer1 = this_board->ai_ns_min;
+ if (cmd->convert_src == TRIG_TIMER) {
devpriv->CntrlReg |= Control_PACER | Control_IRQEN;
- if (mode == 2) {
+ if (cmd->start_src == TRIG_EXT) {
devpriv->ai_et_CntrlReg = devpriv->CntrlReg;
devpriv->CntrlReg &=
~(Control_PACER | Control_ONEFH | Control_GATE);
devpriv->CntrlReg |= Control_EXT;
devpriv->ai_et = 1;
- } else {
+ } else { /* TRIG_NOW */
devpriv->ai_et = 0;
}
- i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,
- &divisor1, &divisor2,
- &devpriv->ai_timer1,
- devpriv->ai_flags);
outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
- if (mode != 2) {
- /* start pacer */
- start_pacer(dev, mode, divisor1, divisor2);
- } else {
- devpriv->ai_et_div1 = divisor1;
- devpriv->ai_et_div2 = divisor2;
- }
- break;
- case 3:
+
+ if (cmd->start_src == TRIG_NOW)
+ pci171x_start_pacer(dev, true);
+ } else { /* TRIG_EXT */
devpriv->CntrlReg |= Control_EXT | Control_IRQEN;
outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
- break;
}
return 0;
struct pci1710_private *devpriv = dev->private;
int err = 0;
int tmp;
- unsigned int divisor1 = 0, divisor2 = 0;
/* Step 1 : check if triggers are trivially valid */
if (cmd->convert_src == TRIG_TIMER) {
tmp = cmd->convert_arg;
- i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,
- &divisor1, &divisor2,
+ i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+ &devpriv->next_divisor1,
+ &devpriv->next_divisor2,
&cmd->convert_arg, cmd->flags);
if (cmd->convert_arg < this_board->ai_ns_min)
cmd->convert_arg = this_board->ai_ns_min;
if (err)
return 4;
- /* step 5: complain about special chanlist considerations */
+ /* Step 5: check channel list */
- if (cmd->chanlist) {
- if (!check_channel_list(dev, s, cmd->chanlist,
- cmd->chanlist_len))
- return 5; /* incorrect channels list */
- }
+ err |= pci171x_ai_check_chanlist(dev, s, cmd);
- return 0;
-}
-
-/*
-==============================================================================
-*/
-static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pci1710_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- devpriv->ai_n_chan = cmd->chanlist_len;
- devpriv->ai_chanlist = cmd->chanlist;
- devpriv->ai_flags = cmd->flags;
- devpriv->ai_data_len = s->async->prealloc_bufsz;
- devpriv->ai_timer1 = 0;
- devpriv->ai_timer2 = 0;
-
- if (cmd->stop_src == TRIG_COUNT)
- devpriv->ai_scans = cmd->stop_arg;
- else
- devpriv->ai_scans = 0;
-
-
- if (cmd->scan_begin_src == TRIG_FOLLOW) { /* mode 1, 2, 3 */
- if (cmd->convert_src == TRIG_TIMER) { /* mode 1 and 2 */
- devpriv->ai_timer1 = cmd->convert_arg;
- return pci171x_ai_docmd_and_mode(cmd->start_src ==
- TRIG_EXT ? 2 : 1, dev,
- s);
- }
- if (cmd->convert_src == TRIG_EXT) { /* mode 3 */
- return pci171x_ai_docmd_and_mode(3, dev, s);
- }
- }
+ if (err)
+ return 5;
- return -1;
+ return 0;
}
/*
outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /* reset any operations */
outb(0, dev->iobase + PCI171x_CLRFIFO); /* clear FIFO */
outb(0, dev->iobase + PCI171x_CLRINT); /* clear INT request */
- start_pacer(dev, -1, 0, 0); /* stop 8254 */
+ pci171x_start_pacer(dev, false);
devpriv->da_ranges = 0;
if (this_board->n_aochan) {
outb(devpriv->da_ranges, dev->iobase + PCI171x_DAREF); /* set DACs to 0..5V */
s->do_cmd = pci171x_ai_cmd;
s->cancel = pci171x_ai_cancel;
}
- devpriv->i8254_osc_base = I8254_OSC_BASE_10MHZ;
subdev++;
}
return retval;
}
-/*
- * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
- */
-static int
-dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum)
+static int dio200_inttrig_start_intr(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
- struct dio200_subdev_intr *subpriv;
+ struct dio200_subdev_intr *subpriv = s->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
unsigned long flags;
int event = 0;
- if (trignum != 0)
+ if (trig_num != cmd->start_arg)
return -EINVAL;
- subpriv = s->private;
-
spin_lock_irqsave(&subpriv->spinlock, flags);
s->async->inttrig = NULL;
if (subpriv->active)
break;
}
- /* Set up start of acquisition. */
- switch (cmd->start_src) {
- case TRIG_INT:
+ if (cmd->start_src == TRIG_INT)
s->async->inttrig = dio200_inttrig_start_intr;
- break;
- default:
- /* TRIG_NOW */
+ else /* TRIG_NOW */
event = dio200_start_intr(dev, s);
- break;
- }
+
spin_unlock_irqrestore(&subpriv->spinlock, flags);
if (event)
spin_lock_irqsave(&subpriv->spinlock, flags);
switch (data[0]) {
case INSN_CONFIG_SET_COUNTER_MODE:
- if (data[1] > (I8254_MODE5 | I8254_BINARY))
+ if (data[1] > (I8254_MODE5 | I8254_BCD))
ret = -EINVAL;
else
dio200_subdev_8254_set_mode(dev, s, chan, data[1]);
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = pc236_intr_insn;
+ s->len_chanlist = 1;
s->do_cmdtest = pc236_intr_cmdtest;
s->do_cmd = pc236_intr_cmd;
s->cancel = pc236_intr_cancel;
unsigned int cached_div1;
unsigned int cached_div2;
unsigned int ao_stop_count;
- short ao_stop_continuous;
unsigned short ao_enab; /* max 16 channels so 'short' will do */
unsigned char intsce;
};
return i;
}
-/*
- * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
- */
-static void
-pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
- unsigned int *nanosec, int round_mode)
-{
- i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
-}
-
/*
* Kills a command running on the AO subdevice.
*/
unsigned long flags;
set_bit(AO_CMD_STARTED, &devpriv->state);
- if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
+ if (cmd->stop_src == TRIG_COUNT && devpriv->ao_stop_count == 0) {
/* An empty acquisition! */
s->async->events |= COMEDI_CB_EOA;
cfc_handle_events(dev, s);
}
/* Determine number of scans available in buffer. */
num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
- if (!devpriv->ao_stop_continuous) {
+ if (cmd->stop_src == TRIG_COUNT) {
/* Fixed number of scans. */
if (num_scans > devpriv->ao_stop_count)
num_scans = devpriv->ao_stop_count;
switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
case PCI224_DACCON_FIFOFL_EMPTY:
room = PCI224_FIFO_ROOM_EMPTY;
- if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
+ if (cmd->stop_src == TRIG_COUNT && devpriv->ao_stop_count == 0) {
/* FIFO empty at end of counted acquisition. */
s->async->events |= COMEDI_CB_EOA;
cfc_handle_events(dev, s);
dev->iobase + PCI224_DACDATA);
}
}
- if (!devpriv->ao_stop_continuous) {
+ if (cmd->stop_src == TRIG_COUNT) {
devpriv->ao_stop_count -= num_scans;
if (devpriv->ao_stop_count == 0) {
/*
cfc_handle_events(dev, s);
}
-/*
- * Internal trigger function to start acquisition on AO subdevice.
- */
-static int
-pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum)
+static int pci224_ao_inttrig_start(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
- if (trignum != 0)
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (trig_num != cmd->start_arg)
return -EINVAL;
s->async->inttrig = NULL;
return 1;
}
+static int pci224_ao_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
+ unsigned int chan_mask = 0;
+ int i;
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+ unsigned int range = CR_RANGE(cmd->chanlist[i]);
+
+ if (chan_mask & (1 << chan)) {
+ dev_dbg(dev->class_dev,
+ "%s: entries in chanlist must contain no duplicate channels\n",
+ __func__);
+ return -EINVAL;
+ }
+ chan_mask |= (1 << chan);
+
+ if (range != range0) {
+ dev_dbg(dev->class_dev,
+ "%s: entries in chanlist must all have the same range index\n",
+ __func__);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
#define MAX_SCAN_PERIOD 0xFFFFFFFFU
#define MIN_SCAN_PERIOD 2500
#define CONVERT_PERIOD 625
/* Step 4: fix up any arguments. */
if (cmd->scan_begin_src == TRIG_TIMER) {
- unsigned int div1, div2, round;
- int round_mode = cmd->flags & TRIG_ROUND_MASK;
-
tmp = cmd->scan_begin_arg;
- /* Check whether to use a single timer. */
- switch (round_mode) {
- case TRIG_ROUND_NEAREST:
- default:
- round = I8254_OSC_BASE_10MHZ / 2;
- break;
- case TRIG_ROUND_DOWN:
- round = 0;
- break;
- case TRIG_ROUND_UP:
- round = I8254_OSC_BASE_10MHZ - 1;
- break;
- }
- /* Be careful to avoid overflow! */
- div2 = cmd->scan_begin_arg / I8254_OSC_BASE_10MHZ;
- div2 += (round + cmd->scan_begin_arg % I8254_OSC_BASE_10MHZ) /
- I8254_OSC_BASE_10MHZ;
- if (div2 <= 0x10000) {
- /* A single timer will suffice. */
- if (div2 < 2)
- div2 = 2;
- cmd->scan_begin_arg = div2 * I8254_OSC_BASE_10MHZ;
- if (cmd->scan_begin_arg < div2 ||
- cmd->scan_begin_arg < I8254_OSC_BASE_10MHZ) {
- /* Overflow! */
- cmd->scan_begin_arg = MAX_SCAN_PERIOD;
- }
- } else {
- /* Use two timers. */
- div1 = devpriv->cached_div1;
- div2 = devpriv->cached_div2;
- pci224_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
- &div1, &div2,
- &cmd->scan_begin_arg,
- round_mode);
- devpriv->cached_div1 = div1;
- devpriv->cached_div2 = div2;
- }
+ /* Use two timers. */
+ i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+ &devpriv->cached_div1,
+ &devpriv->cached_div2,
+ &cmd->scan_begin_arg,
+ cmd->flags);
if (tmp != cmd->scan_begin_arg)
err++;
-
}
if (err)
return 4;
- /* Step 5: check channel list. */
-
- if (cmd->chanlist && (cmd->chanlist_len > 0)) {
- unsigned int range;
- enum { range_err = 1, dupchan_err = 2, };
- unsigned errors;
- unsigned int n;
- unsigned int ch;
-
- /*
- * Check all channels have the same range index. Don't care
- * about analogue reference, as we can't configure it.
- *
- * Check the list has no duplicate channels.
- */
- range = CR_RANGE(cmd->chanlist[0]);
- errors = 0;
- tmp = 0;
- for (n = 0; n < cmd->chanlist_len; n++) {
- ch = CR_CHAN(cmd->chanlist[n]);
- if (tmp & (1U << ch))
- errors |= dupchan_err;
-
- tmp |= (1U << ch);
- if (CR_RANGE(cmd->chanlist[n]) != range)
- errors |= range_err;
-
- }
- if (errors) {
- if (errors & dupchan_err) {
- dev_dbg(dev->class_dev,
- "%s: entries in chanlist must contain no duplicate channels\n",
- __func__);
- }
- if (errors & range_err) {
- dev_dbg(dev->class_dev,
- "%s: entries in chanlist must all have the same range index\n",
- __func__);
- }
- err++;
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= pci224_ao_check_chanlist(dev, s, cmd);
if (err)
return 5;
return 0;
}
-/*
- * 'do_cmd' function for AO subdevice.
- */
+static void pci224_ao_start_pacer(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct pci224_private *devpriv = dev->private;
+ unsigned long timer_base = devpriv->iobase1 + PCI224_Z2_CT0;
+
+ /*
+ * The output of timer Z2-0 will be used as the scan trigger
+ * source.
+ */
+ /* Make sure Z2-0 is gated on. */
+ outb(GAT_CONFIG(0, GAT_VCC), devpriv->iobase1 + PCI224_ZGAT_SCE);
+ /* Cascading with Z2-2. */
+ /* Make sure Z2-2 is gated on. */
+ outb(GAT_CONFIG(2, GAT_VCC), devpriv->iobase1 + PCI224_ZGAT_SCE);
+ /* Z2-2 needs 10 MHz clock. */
+ outb(CLK_CONFIG(2, CLK_10MHZ), devpriv->iobase1 + PCI224_ZCLK_SCE);
+ /* Load Z2-2 mode (2) and counter (div1). */
+ i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
+ i8254_write(timer_base, 0, 2, devpriv->cached_div1);
+ /* Z2-0 is clocked from Z2-2's output. */
+ outb(CLK_CONFIG(0, CLK_OUTNM1), devpriv->iobase1 + PCI224_ZCLK_SCE);
+ /* Load Z2-0 mode (2) and counter (div2). */
+ i8254_set_mode(timer_base, 0, 0, I8254_MODE2 | I8254_BINARY);
+ i8254_write(timer_base, 0, 0, devpriv->cached_div2);
+}
+
static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct pci224_private *devpriv = dev->private;
outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
dev->iobase + PCI224_DACCON);
- if (cmd->scan_begin_src == TRIG_TIMER) {
- unsigned int div1, div2, round;
- unsigned int ns = cmd->scan_begin_arg;
- int round_mode = cmd->flags & TRIG_ROUND_MASK;
-
- /* Check whether to use a single timer. */
- switch (round_mode) {
- case TRIG_ROUND_NEAREST:
- default:
- round = I8254_OSC_BASE_10MHZ / 2;
- break;
- case TRIG_ROUND_DOWN:
- round = 0;
- break;
- case TRIG_ROUND_UP:
- round = I8254_OSC_BASE_10MHZ - 1;
- break;
- }
- /* Be careful to avoid overflow! */
- div2 = cmd->scan_begin_arg / I8254_OSC_BASE_10MHZ;
- div2 += (round + cmd->scan_begin_arg % I8254_OSC_BASE_10MHZ) /
- I8254_OSC_BASE_10MHZ;
- if (div2 <= 0x10000) {
- /* A single timer will suffice. */
- if (div2 < 2)
- div2 = 2;
- div2 &= 0xffff;
- div1 = 1; /* Flag that single timer to be used. */
- } else {
- /* Use two timers. */
- div1 = devpriv->cached_div1;
- div2 = devpriv->cached_div2;
- pci224_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
- &div1, &div2,
- &ns, round_mode);
- }
-
- /*
- * The output of timer Z2-0 will be used as the scan trigger
- * source.
- */
- /* Make sure Z2-0 is gated on. */
- outb(GAT_CONFIG(0, GAT_VCC),
- devpriv->iobase1 + PCI224_ZGAT_SCE);
- if (div1 == 1) {
- /* Not cascading. Z2-0 needs 10 MHz clock. */
- outb(CLK_CONFIG(0, CLK_10MHZ),
- devpriv->iobase1 + PCI224_ZCLK_SCE);
- } else {
- /* Cascading with Z2-2. */
- /* Make sure Z2-2 is gated on. */
- outb(GAT_CONFIG(2, GAT_VCC),
- devpriv->iobase1 + PCI224_ZGAT_SCE);
- /* Z2-2 needs 10 MHz clock. */
- outb(CLK_CONFIG(2, CLK_10MHZ),
- devpriv->iobase1 + PCI224_ZCLK_SCE);
- /* Load Z2-2 mode (2) and counter (div1). */
- i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
- 2, div1, 2);
- /* Z2-0 is clocked from Z2-2's output. */
- outb(CLK_CONFIG(0, CLK_OUTNM1),
- devpriv->iobase1 + PCI224_ZCLK_SCE);
- }
- /* Load Z2-0 mode (2) and counter (div2). */
- i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
- }
+ if (cmd->scan_begin_src == TRIG_TIMER)
+ pci224_ao_start_pacer(dev, s);
/*
* Sort out end of acquisition.
*/
- switch (cmd->stop_src) {
- case TRIG_COUNT:
- /* Fixed number of scans. */
- devpriv->ao_stop_continuous = 0;
+ if (cmd->stop_src == TRIG_COUNT)
devpriv->ao_stop_count = cmd->stop_arg;
- break;
- default:
- /* Continuous scans. */
- devpriv->ao_stop_continuous = 1;
+ else /* TRIG_EXT | TRIG_NONE */
devpriv->ao_stop_count = 0;
- break;
- }
- /*
- * Sort out start of acquisition.
- */
- switch (cmd->start_src) {
- case TRIG_INT:
- spin_lock_irqsave(&devpriv->ao_spinlock, flags);
- s->async->inttrig = &pci224_ao_inttrig_start;
- spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
- break;
- case TRIG_EXT:
+ spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ if (cmd->start_src == TRIG_INT) {
+ s->async->inttrig = pci224_ao_inttrig_start;
+ } else { /* TRIG_EXT */
/* Enable external interrupt trigger to start acquisition. */
- spin_lock_irqsave(&devpriv->ao_spinlock, flags);
devpriv->intsce |= PCI224_INTR_EXT;
outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
- spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
- break;
}
+ spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
return 0;
}
* level threshold (PCI230+/260+). */
unsigned short adcg; /* ADCG register value. */
unsigned char int_en; /* Interrupt enables bits. */
- unsigned char ai_continuous; /* Flag set when cmd->stop_src ==
- * TRIG_NONE - user chooses to stop
- * continuous conversion by
- * cancelation. */
- unsigned char ao_continuous; /* Flag set when cmd->stop_src ==
- * TRIG_NONE - user chooses to stop
- * continuous conversion by
- * cancelation. */
unsigned char ai_bipolar; /* Set if bipolar input range so we
* know to mangle it. */
unsigned char ao_bipolar; /* Set if bipolar output range so we
return i;
}
+static int pci230_ao_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ unsigned int prev_chan = CR_CHAN(cmd->chanlist[0]);
+ unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
+ int i;
+
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+ unsigned int range = CR_RANGE(cmd->chanlist[i]);
+
+ if (chan < prev_chan) {
+ dev_dbg(dev->class_dev,
+ "%s: channel numbers must increase\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (range != range0) {
+ dev_dbg(dev->class_dev,
+ "%s: channels must have the same range\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ prev_chan = chan;
+ }
+
+ return 0;
+}
+
static int pci230_ao_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
if (err)
return 4;
- /* Step 5: check channel list if it exists. */
-
- if (cmd->chanlist && cmd->chanlist_len > 0) {
- enum {
- seq_err = (1 << 0),
- range_err = (1 << 1)
- };
- unsigned int errors;
- unsigned int n;
- unsigned int chan, prev_chan;
- unsigned int range, first_range;
-
- prev_chan = CR_CHAN(cmd->chanlist[0]);
- first_range = CR_RANGE(cmd->chanlist[0]);
- errors = 0;
- for (n = 1; n < cmd->chanlist_len; n++) {
- chan = CR_CHAN(cmd->chanlist[n]);
- range = CR_RANGE(cmd->chanlist[n]);
- /* Channel numbers must strictly increase. */
- if (chan < prev_chan)
- errors |= seq_err;
-
- /* Ranges must be the same. */
- if (range != first_range)
- errors |= range_err;
-
- prev_chan = chan;
- }
- if (errors != 0) {
- err++;
- if ((errors & seq_err) != 0) {
- dev_dbg(dev->class_dev,
- "%s: channel numbers must increase\n",
- __func__);
- }
- if ((errors & range_err) != 0) {
- dev_dbg(dev->class_dev,
- "%s: channels must have the same range\n",
- __func__);
- }
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= pci230_ao_check_chanlist(dev, s, cmd);
if (err)
return 5;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
- if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0))
+ if (cmd->stop_src == TRIG_COUNT && devpriv->ao_scan_count == 0)
return;
for (i = 0; i < cmd->chanlist_len; i++) {
/* Read sample from Comedi's circular buffer. */
pci230_ao_write_nofifo(dev, data, CR_CHAN(cmd->chanlist[i]));
}
async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
- if (!devpriv->ao_continuous) {
+ if (cmd->stop_src == TRIG_COUNT) {
devpriv->ao_scan_count--;
if (devpriv->ao_scan_count == 0) {
/* End of acquisition. */
/* Determine number of scans available in buffer. */
bytes_per_scan = cmd->chanlist_len * sizeof(short);
num_scans = comedi_buf_read_n_available(async) / bytes_per_scan;
- if (!devpriv->ao_continuous) {
+ if (cmd->stop_src == TRIG_COUNT) {
/* Fixed number of scans. */
if (num_scans > devpriv->ao_scan_count)
num_scans = devpriv->ao_scan_count;
}
}
events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK;
- if (!devpriv->ao_continuous) {
+ if (cmd->stop_src == TRIG_COUNT) {
devpriv->ao_scan_count -= num_scans;
if (devpriv->ao_scan_count == 0) {
/* All data for the command has been written
unsigned long irqflags;
set_bit(AO_CMD_STARTED, &devpriv->state);
- if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) {
+ if (cmd->stop_src == TRIG_COUNT && devpriv->ao_scan_count == 0) {
/* An empty acquisition! */
async->events |= COMEDI_CB_EOA;
pci230_ao_stop(dev, s);
struct comedi_subdevice *s,
unsigned int trig_num)
{
- if (trig_num != 0)
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (trig_num != cmd->start_src)
return -EINVAL;
s->async->inttrig = NULL;
}
/* Get number of scans required. */
- if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_src == TRIG_COUNT)
devpriv->ao_scan_count = cmd->stop_arg;
- devpriv->ao_continuous = 0;
- } else {
- /* TRIG_NONE, user calls cancel. */
+ else /* TRIG_NONE, user calls cancel */
devpriv->ao_scan_count = 0;
- devpriv->ao_continuous = 1;
- }
/* Set range - see analogue output range table; 0 => unipolar 10V,
* 1 => bipolar +/-10V range scale */
return !err;
}
+static int pci230_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ struct pci230_private *devpriv = dev->private;
+ unsigned int max_diff_chan = (s->n_chan / 2) - 1;
+ unsigned int prev_chan = 0;
+ unsigned int prev_range = 0;
+ unsigned int prev_aref = 0;
+ unsigned int prev_polarity = 0;
+ unsigned int subseq_len = 0;
+ int i;
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ unsigned int chanspec = cmd->chanlist[i];
+ unsigned int chan = CR_CHAN(chanspec);
+ unsigned int range = CR_RANGE(chanspec);
+ unsigned int aref = CR_AREF(chanspec);
+ unsigned int polarity = pci230_ai_bipolar[range];
+
+ if (aref == AREF_DIFF && chan >= max_diff_chan) {
+ dev_dbg(dev->class_dev,
+ "%s: differential channel number out of range 0 to %u\n",
+ __func__, max_diff_chan);
+ return -EINVAL;
+ }
+
+ if (i > 0) {
+ /*
+ * Channel numbers must strictly increase or
+ * subsequence must repeat exactly.
+ */
+ if (chan <= prev_chan && subseq_len == 0)
+ subseq_len = i;
+
+ if (subseq_len > 0 &&
+ cmd->chanlist[i % subseq_len] != chanspec) {
+ dev_dbg(dev->class_dev,
+ "%s: channel numbers must increase or sequence must repeat exactly\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (aref != prev_aref) {
+ dev_dbg(dev->class_dev,
+ "%s: channel sequence analogue references must be all the same (single-ended or differential)\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (polarity != prev_polarity) {
+ dev_dbg(dev->class_dev,
+ "%s: channel sequence ranges must be all bipolar or all unipolar\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (aref != AREF_DIFF && range != prev_range &&
+ ((chan ^ prev_chan) & ~1) == 0) {
+ dev_dbg(dev->class_dev,
+ "%s: single-ended channel pairs must have the same range\n",
+ __func__);
+ return -EINVAL;
+ }
+ }
+ prev_chan = chan;
+ prev_range = range;
+ prev_aref = aref;
+ prev_polarity = polarity;
+ }
+
+ if (subseq_len == 0)
+ subseq_len = cmd->chanlist_len;
+
+ if ((cmd->chanlist_len % subseq_len) != 0) {
+ dev_dbg(dev->class_dev,
+ "%s: sequence must repeat exactly\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * Buggy PCI230+ or PCI260+ requires channel 0 to be (first) in the
+ * sequence if the sequence contains more than one channel. Hardware
+ * versions 1 and 2 have the bug. There is no hardware version 3.
+ *
+ * Actually, there are two firmwares that report themselves as
+ * hardware version 1 (the boards have different ADC chips with
+ * slightly different timing requirements, which was supposed to
+ * be invisible to software). The first one doesn't seem to have
+ * the bug, but the second one does, and we can't tell them apart!
+ */
+ if (devpriv->hwver > 0 && devpriv->hwver < 4) {
+ if (subseq_len > 1 && CR_CHAN(cmd->chanlist[0]) != 0) {
+ dev_info(dev->class_dev,
+ "amplc_pci230: ai_cmdtest: Buggy PCI230+/260+ h/w version %u requires first channel of multi-channel sequence to be 0 (corrected in h/w version 4)\n",
+ devpriv->hwver);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int pci230_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
if (err)
return 4;
- /* Step 5: check channel list if it exists. */
-
- if (cmd->chanlist && cmd->chanlist_len > 0) {
- enum {
- seq_err = 1 << 0,
- rangepair_err = 1 << 1,
- polarity_err = 1 << 2,
- aref_err = 1 << 3,
- diffchan_err = 1 << 4,
- buggy_chan0_err = 1 << 5
- };
- unsigned int errors;
- unsigned int chan, prev_chan;
- unsigned int range, prev_range;
- unsigned int polarity, prev_polarity;
- unsigned int aref, prev_aref;
- unsigned int subseq_len;
- unsigned int n;
-
- subseq_len = 0;
- errors = 0;
- prev_chan = prev_aref = prev_range = prev_polarity = 0;
- for (n = 0; n < cmd->chanlist_len; n++) {
- chan = CR_CHAN(cmd->chanlist[n]);
- range = CR_RANGE(cmd->chanlist[n]);
- aref = CR_AREF(cmd->chanlist[n]);
- polarity = pci230_ai_bipolar[range];
- /* Only the first half of the channels are available if
- * differential. (These are remapped in software. In
- * hardware, only the even channels are available.) */
- if ((aref == AREF_DIFF)
- && (chan >= (s->n_chan / 2))) {
- errors |= diffchan_err;
- }
- if (n > 0) {
- /* Channel numbers must strictly increase or
- * subsequence must repeat exactly. */
- if ((chan <= prev_chan)
- && (subseq_len == 0)) {
- subseq_len = n;
- }
- if ((subseq_len > 0)
- && (cmd->chanlist[n] !=
- cmd->chanlist[n % subseq_len])) {
- errors |= seq_err;
- }
- /* Channels must have same AREF. */
- if (aref != prev_aref)
- errors |= aref_err;
-
- /* Channel ranges must have same polarity. */
- if (polarity != prev_polarity)
- errors |= polarity_err;
-
- /* Single-ended channel pairs must have same
- * range. */
- if ((aref != AREF_DIFF)
- && (((chan ^ prev_chan) & ~1) == 0)
- && (range != prev_range)) {
- errors |= rangepair_err;
- }
- }
- prev_chan = chan;
- prev_range = range;
- prev_aref = aref;
- prev_polarity = polarity;
- }
- if (subseq_len == 0) {
- /* Subsequence is whole sequence. */
- subseq_len = n;
- }
- /* If channel list is a repeating subsequence, need a whole
- * number of repeats. */
- if ((n % subseq_len) != 0)
- errors |= seq_err;
-
- if ((devpriv->hwver > 0) && (devpriv->hwver < 4)) {
- /*
- * Buggy PCI230+ or PCI260+ requires channel 0 to be
- * (first) in the sequence if the sequence contains
- * more than one channel. Hardware versions 1 and 2
- * have the bug. There is no hardware version 3.
- *
- * Actually, there are two firmwares that report
- * themselves as hardware version 1 (the boards
- * have different ADC chips with slightly different
- * timing requirements, which was supposed to be
- * invisible to software). The first one doesn't
- * seem to have the bug, but the second one
- * does, and we can't tell them apart!
- */
- if ((subseq_len > 1)
- && (CR_CHAN(cmd->chanlist[0]) != 0)) {
- errors |= buggy_chan0_err;
- }
- }
- if (errors != 0) {
- err++;
- if ((errors & seq_err) != 0) {
- dev_dbg(dev->class_dev,
- "%s: channel numbers must increase or sequence must repeat exactly\n",
- __func__);
- }
- if ((errors & rangepair_err) != 0) {
- dev_dbg(dev->class_dev,
- "%s: single-ended channel pairs must have the same range\n",
- __func__);
- }
- if ((errors & polarity_err) != 0) {
- dev_dbg(dev->class_dev,
- "%s: channel sequence ranges must be all bipolar or all unipolar\n",
- __func__);
- }
- if ((errors & aref_err) != 0) {
- dev_dbg(dev->class_dev,
- "%s: channel sequence analogue references must be all the same (single-ended or differential)\n",
- __func__);
- }
- if ((errors & diffchan_err) != 0) {
- dev_dbg(dev->class_dev,
- "%s: differential channel number out of range 0 to %u\n",
- __func__, (s->n_chan / 2) - 1);
- }
- if ((errors & buggy_chan0_err) != 0) {
- dev_info(dev->class_dev,
- "amplc_pci230: ai_cmdtest: Buggy PCI230+/260+ h/w version %u requires first channel of multi-channel sequence to be 0 (corrected in h/w version 4)\n",
- devpriv->hwver);
- }
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= pci230_ai_check_chanlist(dev, s, cmd);
if (err)
return 5;
/* Wake at end of scan. */
wake = scanlen - devpriv->ai_scan_pos;
} else {
- if (devpriv->ai_continuous
- || (devpriv->ai_scan_count >= PCI230_ADC_FIFOLEVEL_HALFFULL)
- || (scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL)) {
+ if (cmd->stop_src != TRIG_COUNT ||
+ devpriv->ai_scan_count >= PCI230_ADC_FIFOLEVEL_HALFFULL ||
+ scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
wake = PCI230_ADC_FIFOLEVEL_HALFFULL;
} else {
wake = (devpriv->ai_scan_count * scanlen)
struct comedi_cmd *cmd = &async->cmd;
set_bit(AI_CMD_STARTED, &devpriv->state);
- if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
+ if (cmd->stop_src == TRIG_COUNT && devpriv->ai_scan_count == 0) {
/* An empty acquisition! */
async->events |= COMEDI_CB_EOA;
pci230_ai_stop(dev, s);
struct comedi_subdevice *s,
unsigned int trig_num)
{
- if (trig_num != 0)
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (trig_num != cmd->start_arg)
return -EINVAL;
s->async->inttrig = NULL;
struct comedi_subdevice *s)
{
struct pci230_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
unsigned int events = 0;
unsigned int status_fifo;
unsigned int i;
unsigned int scanlen = async->cmd.scan_end_arg;
/* Determine number of samples to read. */
- if (devpriv->ai_continuous) {
+ if (cmd->stop_src != TRIG_COUNT) {
todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
} else if (devpriv->ai_scan_count == 0) {
todo = 0;
async->events |= COMEDI_CB_EOS;
}
}
- if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
+ if (cmd->stop_src == TRIG_COUNT && devpriv->ai_scan_count == 0) {
/* End of acquisition. */
events |= COMEDI_CB_EOA;
} else {
/* Get number of scans required. */
- if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_src == TRIG_COUNT)
devpriv->ai_scan_count = cmd->stop_arg;
- devpriv->ai_continuous = 0;
- } else {
- /* TRIG_NONE, user calls cancel. */
+ else /* TRIG_NONE, user calls cancel */
devpriv->ai_scan_count = 0;
- devpriv->ai_continuous = 1;
- }
devpriv->ai_scan_pos = 0; /* Position within scan. */
/* Steps;
}
}
- if (cmd->start_src == TRIG_INT) {
+ if (cmd->start_src == TRIG_INT)
s->async->inttrig = pci230_ai_inttrig_start;
- } else {
- /* TRIG_NOW */
+ else /* TRIG_NOW */
pci230_ai_start(dev, s);
- }
return 0;
}
return 1;
}
+static int cb_pcidas_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
+ unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
+ int i;
+
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+ unsigned int range = CR_RANGE(cmd->chanlist[i]);
+
+ if (chan != (chan0 + i) % s->n_chan) {
+ dev_dbg(dev->class_dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ return -EINVAL;
+ }
+
+ if (range != range0) {
+ dev_dbg(dev->class_dev,
+ "entries in chanlist must all have the same gain\n");
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
struct cb_pcidas_private *devpriv = dev->private;
int err = 0;
int tmp;
- int i, gain, start_chan;
/* Step 1 : check if triggers are trivially valid */
if (err)
return 2;
- /* step 3: arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
switch (cmd->start_src) {
+ case TRIG_NOW:
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ break;
case TRIG_EXT:
/* External trigger, only CR_EDGE and CR_INVERT flags allowed */
if ((cmd->start_arg
err |= -EINVAL;
}
break;
- default:
- err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- break;
}
if (cmd->scan_begin_src == TRIG_TIMER)
if (err)
return 4;
- /* check channel/gain list against card's limitations */
- if (cmd->chanlist) {
- gain = CR_RANGE(cmd->chanlist[0]);
- start_chan = CR_CHAN(cmd->chanlist[0]);
- for (i = 1; i < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i]) !=
- (start_chan + i) % s->n_chan) {
- comedi_error(dev,
- "entries in chanlist must be consecutive channels, counting upwards\n");
- err++;
- }
- if (CR_RANGE(cmd->chanlist[i]) != gain) {
- comedi_error(dev,
- "entries in chanlist must all have the same gain\n");
- err++;
- }
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= cb_pcidas_ai_check_chanlist(dev, s, cmd);
if (err)
return 5;
return 0;
}
-static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
- int rounding_flags)
+static void cb_pcidas_ai_load_counters(struct comedi_device *dev)
{
struct cb_pcidas_private *devpriv = dev->private;
+ unsigned long timer_base = devpriv->pacer_counter_dio + ADC8254;
- i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
- &devpriv->divisor1, &devpriv->divisor2,
- ns, rounding_flags);
+ i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
+ i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
- /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
- i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
- devpriv->divisor1, 2);
- i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
- devpriv->divisor2, 2);
+ i8254_write(timer_base, 0, 1, devpriv->divisor1);
+ i8254_write(timer_base, 0, 2, devpriv->divisor2);
}
static int cb_pcidas_ai_cmd(struct comedi_device *dev,
outw(bits, devpriv->control_status + ADCMUX_CONT);
/* load counters */
- if (cmd->convert_src == TRIG_TIMER)
- cb_pcidas_load_counters(dev, &cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
- else if (cmd->scan_begin_src == TRIG_TIMER)
- cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ if (cmd->scan_begin_src == TRIG_TIMER || cmd->convert_src == TRIG_TIMER)
+ cb_pcidas_ai_load_counters(dev);
/* set number of conversions */
if (cmd->stop_src == TRIG_COUNT)
return 0;
}
+static int cb_pcidas_ao_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
+
+ if (cmd->chanlist_len > 1) {
+ unsigned int chan1 = CR_CHAN(cmd->chanlist[1]);
+
+ if (chan0 != 0 || chan1 != 1) {
+ dev_dbg(dev->class_dev,
+ "channels must be ordered channel 0, channel 1 in chanlist\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
if (err)
return 4;
- /* check channel/gain list against card's limitations */
- if (cmd->chanlist && cmd->chanlist_len > 1) {
- if (CR_CHAN(cmd->chanlist[0]) != 0 ||
- CR_CHAN(cmd->chanlist[1]) != 1) {
- comedi_error(dev,
- "channels must be ordered channel 0, channel 1 in chanlist\n");
- err++;
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= cb_pcidas_ao_check_chanlist(dev, s, cmd);
if (err)
return 5;
struct comedi_cmd *cmd = &s->async->cmd;
unsigned long flags;
- if (trig_num != 0)
+ if (trig_num != cmd->start_arg)
return -EINVAL;
/* load up fifo */
return 0;
}
+static void cb_pcidas_ao_load_counters(struct comedi_device *dev)
+{
+ struct cb_pcidas_private *devpriv = dev->private;
+ unsigned long timer_base = devpriv->pacer_counter_dio + DAC8254;
+
+ i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
+ i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
+
+ i8254_write(timer_base, 0, 1, devpriv->ao_divisor1);
+ i8254_write(timer_base, 0, 2, devpriv->ao_divisor2);
+}
+
static int cb_pcidas_ao_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
outw(0, devpriv->ao_registers + DACFIFOCLR);
/* load counters */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
- &devpriv->ao_divisor1,
- &devpriv->ao_divisor2,
- &cmd->scan_begin_arg, cmd->flags);
+ if (cmd->scan_begin_src == TRIG_TIMER)
+ cb_pcidas_ao_load_counters(dev);
- /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
- i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
- devpriv->ao_divisor1, 2);
- i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
- devpriv->ao_divisor2, 2);
- }
/* set number of conversions */
if (cmd->stop_src == TRIG_COUNT)
devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
return;
}
+static int cb_pcidas64_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ const struct pcidas64_board *board = comedi_board(dev);
+ unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
+ int i;
+
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ unsigned int aref = CR_AREF(cmd->chanlist[i]);
+
+ if (aref != aref0) {
+ dev_dbg(dev->class_dev,
+ "all elements in chanlist must use the same analog reference\n");
+ return -EINVAL;
+ }
+ }
+
+ if (board->layout == LAYOUT_4020) {
+ unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
+
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+
+ if (chan != (chan0 + i)) {
+ dev_dbg(dev->class_dev,
+ "chanlist must use consecutive channels\n");
+ return -EINVAL;
+ }
+ }
+ if (cmd->chanlist_len == 3) {
+ dev_dbg(dev->class_dev,
+ "chanlist cannot be 3 channels long, use 1, 2, or 4 channels\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
const struct pcidas64_board *thisboard = comedi_board(dev);
int err = 0;
unsigned int tmp_arg, tmp_arg2;
- int i;
- int aref;
unsigned int triggers;
/* Step 1 : check if triggers are trivially valid */
if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
err |= -EINVAL;
- if (cmd->stop_src != TRIG_COUNT &&
- cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
- err |= -EINVAL;
if (err)
return 2;
/* Step 3: check if arguments are trivially valid */
+ switch (cmd->start_src) {
+ case TRIG_NOW:
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ break;
+ case TRIG_EXT:
+ /*
+ * start_arg is the CR_CHAN | CR_INVERT of the
+ * external trigger.
+ */
+ break;
+ }
+
if (cmd->convert_src == TRIG_TIMER) {
if (thisboard->layout == LAYOUT_4020) {
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
if (err)
return 4;
- /* make sure user is doesn't change analog reference mid chanlist */
- if (cmd->chanlist) {
- aref = CR_AREF(cmd->chanlist[0]);
- for (i = 1; i < cmd->chanlist_len; i++) {
- if (aref != CR_AREF(cmd->chanlist[i])) {
- comedi_error(dev,
- "all elements in chanlist must use the same analog reference");
- err++;
- break;
- }
- }
- /* check 4020 chanlist */
- if (thisboard->layout == LAYOUT_4020) {
- unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
- for (i = 1; i < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i]) !=
- first_channel + i) {
- comedi_error(dev,
- "chanlist must use consecutive channels");
- err++;
- break;
- }
- }
- if (cmd->chanlist_len == 3) {
- comedi_error(dev,
- "chanlist cannot be 3 channels long, use 1, 2, or 4 channels");
- err++;
- }
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= cb_pcidas64_ai_check_chanlist(dev, s, cmd);
if (err)
return 5;
struct comedi_cmd *cmd = &s->async->cmd;
int retval;
- if (trig_num != 0)
+ if (trig_num != cmd->start_arg)
return -EINVAL;
retval = prep_ao_dma(dev, cmd);
return 0;
}
+static int cb_pcidas64_ao_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
+ int i;
+
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+
+ if (chan != (chan0 + i)) {
+ dev_dbg(dev->class_dev,
+ "chanlist must use consecutive channels\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
const struct pcidas64_board *thisboard = comedi_board(dev);
int err = 0;
unsigned int tmp_arg;
- int i;
/* Step 1 : check if triggers are trivially valid */
/* Step 3: check if arguments are trivially valid */
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+
if (cmd->scan_begin_src == TRIG_TIMER) {
err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
thisboard->ao_scan_speed);
if (err)
return 4;
- if (cmd->chanlist) {
- unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
- for (i = 1; i < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i]) != first_channel + i) {
- comedi_error(dev,
- "chanlist must use consecutive channels");
- err++;
- break;
- }
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= cb_pcidas64_ao_check_chanlist(dev, s, cmd);
if (err)
return 5;
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = parport_intr_insn_bits;
+ s->len_chanlist = 1;
s->do_cmdtest = parport_intr_cmdtest;
s->do_cmd = parport_intr_cmd;
s->cancel = parport_intr_cancel;
s->n_chan = N_CHANS;
s->maxdata = 0xffff;
s->range_table = &waveform_ai_ranges;
- s->len_chanlist = s->n_chan * 2;
s->insn_write = waveform_ao_insn_write;
- s->do_cmd = NULL;
- s->do_cmdtest = NULL;
- s->cancel = NULL;
/* Our default loopback value is just a 0V flatline */
for (i = 0; i < s->n_chan; i++)
mod_timer(&devpriv->timer, jiffies + timer_period());
}
+static int das16_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
+ unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
+ int i;
+
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+ unsigned int range = CR_RANGE(cmd->chanlist[i]);
+
+ if (chan != ((chan0 + i) % s->n_chan)) {
+ dev_dbg(dev->class_dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ return -EINVAL;
+ }
+
+ if (range != range0) {
+ dev_dbg(dev->class_dev,
+ "entries in chanlist must all have the same gain\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
const struct das16_board *board = comedi_board(dev);
struct das16_private_struct *devpriv = dev->private;
int err = 0, tmp;
- int gain, start_chan, i;
int mask;
/* Step 1 : check if triggers are trivially valid */
if (err)
return 4;
- /* check channel/gain list against card's limitations */
- if (cmd->chanlist) {
- gain = CR_RANGE(cmd->chanlist[0]);
- start_chan = CR_CHAN(cmd->chanlist[0]);
- for (i = 1; i < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i]) !=
- (start_chan + i) % s->n_chan) {
- dev_err(dev->class_dev,
- "entries in chanlist must be consecutive channels, counting upwards\n");
- err++;
- }
- if (CR_RANGE(cmd->chanlist[i]) != gain) {
- dev_err(dev->class_dev,
- "entries in chanlist must all have the same gain\n");
- err++;
- }
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= das16_ai_check_chanlist(dev, s, cmd);
+
if (err)
return 5;
&devpriv->divisor1, &devpriv->divisor2,
&ns, rounding_flags);
- /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
- i8254_load(timer_base, 0, 1, devpriv->divisor1, 2);
- i8254_load(timer_base, 0, 2, devpriv->divisor2, 2);
+ i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
+ i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
+ i8254_write(timer_base, 0, 1, devpriv->divisor1);
+ i8254_write(timer_base, 0, 2, devpriv->divisor2);
return ns;
}
array[i] = munge_sample(array[i]);
}
+static int das16m1_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ int i;
+
+ if (cmd->chanlist_len == 1)
+ return 0;
+
+ if ((cmd->chanlist_len % 2) != 0) {
+ dev_dbg(dev->class_dev,
+ "chanlist must be of even length or length 1\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+
+ if ((i % 2) != (chan % 2)) {
+ dev_dbg(dev->class_dev,
+ "even/odd channels must go have even/odd chanlist indices\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int das16m1_cmd_test(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
struct das16m1_private_struct *devpriv = dev->private;
- unsigned int err = 0, tmp, i;
+ unsigned int err = 0, tmp;
/* Step 1 : check if triggers are trivially valid */
if (err)
return 4;
- /* check chanlist against board's peculiarities */
- if (cmd->chanlist && cmd->chanlist_len > 1) {
- for (i = 0; i < cmd->chanlist_len; i++) {
- /* even/odd channels must go into even/odd queue addresses */
- if ((i % 2) != (CR_CHAN(cmd->chanlist[i]) % 2)) {
- comedi_error(dev, "bad chanlist:\n"
- " even/odd channels must go have even/odd chanlist indices");
- err++;
- }
- }
- if ((cmd->chanlist_len % 2) != 0) {
- comedi_error(dev,
- "chanlist must be of even length or length 1");
- err++;
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= das16m1_ai_check_chanlist(dev, s, cmd);
if (err)
return 5;
return 0;
}
-/* This function takes a time in nanoseconds and sets the *
- * 2 pacer clocks to the closest frequency possible. It also *
- * returns the actual sampling period. */
-static unsigned int das16m1_set_pacer(struct comedi_device *dev,
- unsigned int ns, int rounding_flags)
+static void das16m1_set_pacer(struct comedi_device *dev)
{
struct das16m1_private_struct *devpriv = dev->private;
+ unsigned long timer_base = dev->iobase + DAS16M1_8254_SECOND;
- i8253_cascade_ns_to_timer_2div(I8254_OSC_BASE_10MHZ,
- &devpriv->divisor1,
- &devpriv->divisor2,
- &ns, rounding_flags);
-
- /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
- i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 1, devpriv->divisor1,
- 2);
- i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 2, devpriv->divisor2,
- 2);
+ i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
+ i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
- return ns;
+ i8254_write(timer_base, 0, 1, devpriv->divisor1);
+ i8254_write(timer_base, 0, 2, devpriv->divisor2);
}
static int das16m1_cmd_exec(struct comedi_device *dev,
struct das16m1_private_struct *devpriv = dev->private;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
+ unsigned long timer_base = dev->iobase + DAS16M1_8254_FIRST;
unsigned int byte, i;
/* disable interrupts and internal pacer */
/* Initialize lower half of hardware counter, used to determine how
* many samples are in fifo. Value doesn't actually load into counter
* until counter's next clock (the next a/d conversion) */
- i8254_load(dev->iobase + DAS16M1_8254_FIRST, 0, 1, 0, 2);
+ i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
+ i8254_write(timer_base, 0, 1, 0);
/* remember current reading of counter so we know when counter has
* actually been loaded */
- devpriv->initial_hw_count =
- i8254_read(dev->iobase + DAS16M1_8254_FIRST, 0, 1);
+ devpriv->initial_hw_count = i8254_read(timer_base, 0, 1);
/* setup channel/gain queue */
for (i = 0; i < cmd->chanlist_len; i++) {
outb(i, dev->iobase + DAS16M1_QUEUE_ADDR);
outb(byte, dev->iobase + DAS16M1_QUEUE_DATA);
}
- /* set counter mode and counts */
- cmd->convert_arg =
- das16m1_set_pacer(dev, cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ /* enable interrupts and set internal pacer counter mode and counts */
+ devpriv->control_state &= ~PACER_MASK;
+ if (cmd->convert_src == TRIG_TIMER) {
+ das16m1_set_pacer(dev);
+ devpriv->control_state |= INT_PACER;
+ } else { /* TRIG_EXT */
+ devpriv->control_state |= EXT_PACER;
+ }
/* set control & status register */
byte = 0;
/* clear interrupt bit */
outb(0, dev->iobase + DAS16M1_CLEAR_INTR);
- /* enable interrupts and internal pacer */
- devpriv->control_state &= ~PACER_MASK;
- if (cmd->convert_src == TRIG_TIMER)
- devpriv->control_state |= INT_PACER;
- else
- devpriv->control_state |= EXT_PACER;
-
devpriv->control_state |= INTE;
outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
/* converts requested conversion timing to timing compatible with
* hardware, used only when card is in 'burst mode'
*/
-static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
+static unsigned int burst_convert_arg(unsigned int convert_arg, int flags)
{
unsigned int micro_sec;
convert_arg = 64000;
/* the conversion time must be an integral number of microseconds */
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
micro_sec = (convert_arg + 500) / 1000;
return micro_sec * 1000;
}
+static int das1800_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ unsigned int unipolar0 = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
+ int i;
+
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ unsigned int unipolar = CR_RANGE(cmd->chanlist[i]) & UNIPOLAR;
+
+ if (unipolar != unipolar0) {
+ dev_dbg(dev->class_dev,
+ "unipolar and bipolar ranges cannot be mixed in the chanlist\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
/* test analog input cmd */
static int das1800_ai_do_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
const struct das1800_board *thisboard = comedi_board(dev);
struct das1800_private *devpriv = dev->private;
int err = 0;
- unsigned int tmp_arg;
- int i;
- int unipolar;
+ unsigned int arg;
/* Step 1 : check if triggers are trivially valid */
/* step 4: fix up any arguments */
- if (cmd->convert_src == TRIG_TIMER) {
- /* if we are not in burst mode */
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- tmp_arg = cmd->convert_arg;
- /* calculate counter values that give desired timing */
+ if (cmd->scan_begin_src == TRIG_FOLLOW &&
+ cmd->convert_src == TRIG_TIMER) {
+ /* we are not in burst mode */
+ arg = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
+ &devpriv->divisor1,
+ &devpriv->divisor2,
+ &cmd->convert_arg, cmd->flags);
+ if (arg != cmd->convert_arg)
+ err++;
+ } else if (cmd->convert_src == TRIG_TIMER) {
+ /* we are in burst mode */
+ arg = cmd->convert_arg;
+ cmd->convert_arg = burst_convert_arg(cmd->convert_arg,
+ cmd->flags);
+ if (arg != cmd->convert_arg)
+ err++;
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ arg = cmd->convert_arg * cmd->chanlist_len;
+ if (arg > cmd->scan_begin_arg) {
+ cmd->scan_begin_arg = arg;
+ err++;
+ }
+
+ arg = cmd->scan_begin_arg;
i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
&devpriv->divisor1,
&devpriv->divisor2,
- &cmd->convert_arg,
+ &cmd->scan_begin_arg,
cmd->flags);
- if (tmp_arg != cmd->convert_arg)
- err++;
- }
- /* if we are in burst mode */
- else {
- /* check that convert_arg is compatible */
- tmp_arg = cmd->convert_arg;
- cmd->convert_arg =
- burst_convert_arg(cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
- if (tmp_arg != cmd->convert_arg)
+ if (arg != cmd->scan_begin_arg)
err++;
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* if scans are timed faster than conversion rate allows */
- if (cmd->convert_arg * cmd->chanlist_len >
- cmd->scan_begin_arg) {
- cmd->scan_begin_arg =
- cmd->convert_arg *
- cmd->chanlist_len;
- err++;
- }
- tmp_arg = cmd->scan_begin_arg;
- /* calculate counter values that give desired timing */
- i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
- &devpriv->divisor1,
- &devpriv->divisor2,
- &cmd->scan_begin_arg,
- cmd->flags);
- if (tmp_arg != cmd->scan_begin_arg)
- err++;
- }
}
}
if (err)
return 4;
- /* make sure user is not trying to mix unipolar and bipolar ranges */
- if (cmd->chanlist) {
- unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
- for (i = 1; i < cmd->chanlist_len; i++) {
- if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
- comedi_error(dev,
- "unipolar and bipolar ranges cannot be mixed in the chanlist");
- err++;
- break;
- }
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= das1800_ai_check_chanlist(dev, s, cmd);
if (err)
return 5;
return control_c;
}
-/* loads counters with divisor1, divisor2 from private structure */
-static int das1800_set_frequency(struct comedi_device *dev)
+static void das1800_setup_counters(struct comedi_device *dev,
+ const struct comedi_cmd *cmd)
{
struct das1800_private *devpriv = dev->private;
- int err = 0;
-
- /* counter 1, mode 2 */
- if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
- 2))
- err++;
- /* counter 2, mode 2 */
- if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
- 2))
- err++;
- if (err)
- return -1;
+ unsigned long timer_base = dev->iobase + DAS1800_COUNTER;
- return 0;
-}
-
-/* sets up counters */
-static int setup_counters(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- struct das1800_private *devpriv = dev->private;
- unsigned int period;
+ /* setup cascaded counters for conversion/scan frequency */
+ if ((cmd->scan_begin_src == TRIG_FOLLOW ||
+ cmd->scan_begin_src == TRIG_TIMER) &&
+ cmd->convert_src == TRIG_TIMER) {
+ i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
+ i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
- /* setup cascaded counters for conversion/scan frequency */
- switch (cmd->scan_begin_src) {
- case TRIG_FOLLOW: /* not in burst mode */
- if (cmd->convert_src == TRIG_TIMER) {
- /* set conversion frequency */
- period = cmd->convert_arg;
- i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
- &devpriv->divisor1,
- &devpriv->divisor2,
- &period, cmd->flags);
- if (das1800_set_frequency(dev) < 0)
- return -1;
- }
- break;
- case TRIG_TIMER: /* in burst mode */
- /* set scan frequency */
- period = cmd->scan_begin_arg;
- i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
- &devpriv->divisor1,
- &devpriv->divisor2,
- &period, cmd->flags);
- if (das1800_set_frequency(dev) < 0)
- return -1;
- break;
- default:
- break;
+ i8254_write(timer_base, 0, 1, devpriv->divisor1);
+ i8254_write(timer_base, 0, 2, devpriv->divisor2);
}
- /* setup counter 0 for 'about triggering' */
+ /* setup counter 0 for 'about triggering' */
if (cmd->stop_src == TRIG_EXT) {
- /* load counter 0 in mode 0 */
- i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
- }
+ i8254_set_mode(timer_base, 0, 0, I8254_MODE0 | I8254_BINARY);
- return 0;
+ i8254_write(timer_base, 0, 0, 1);
+ }
}
/* utility function that suggests a dma transfer size based on the conversion period 'ns' */
struct comedi_subdevice *s)
{
struct das1800_private *devpriv = dev->private;
- int ret;
int control_a, control_c;
struct comedi_async *async = s->async;
const struct comedi_cmd *cmd = &async->cmd;
/* setup card and start */
program_chanlist(dev, cmd);
- ret = setup_counters(dev, cmd);
- if (ret < 0) {
- comedi_error(dev, "Error setting up counters");
- return ret;
- }
+ das1800_setup_counters(dev, cmd);
setup_dma(dev, cmd);
outb(control_c, dev->iobase + DAS1800_CONTROL_C);
/* set conversion rate and length for burst mode */
static int das1800_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- const struct das1800_board *thisboard = comedi_board(dev);
+ const struct das1800_board *thisboard;
struct das1800_private *devpriv;
struct comedi_subdevice *s;
unsigned int irq = it->options[1];
unsigned int maxdata;
};
-struct das6402_boardinfo das6402_boards[] = {
+static struct das6402_boardinfo das6402_boards[] = {
{
.name = "das6402-12",
.maxdata = 0x0fff,
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
}
-static int das800_set_frequency(struct comedi_device *dev)
+static void das800_set_frequency(struct comedi_device *dev)
{
struct das800_private *devpriv = dev->private;
- int err = 0;
-
- if (i8254_load(dev->iobase + DAS800_8254, 0, 1, devpriv->divisor1, 2))
- err++;
- if (i8254_load(dev->iobase + DAS800_8254, 0, 2, devpriv->divisor2, 2))
- err++;
- if (err)
- return -1;
+ unsigned long timer_base = dev->iobase + DAS800_8254;
- return 0;
+ i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
+ i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
+ i8254_write(timer_base, 0, 1, devpriv->divisor1);
+ i8254_write(timer_base, 0, 2, devpriv->divisor2);
}
static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
return 0;
}
+static int das800_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
+ unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
+ int i;
+
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+ unsigned int range = CR_RANGE(cmd->chanlist[i]);
+
+ if (chan != (chan0 + i) % s->n_chan) {
+ dev_dbg(dev->class_dev,
+ "chanlist must be consecutive, counting upwards\n");
+ return -EINVAL;
+ }
+
+ if (range != range0) {
+ dev_dbg(dev->class_dev,
+ "chanlist must all have the same gain\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int das800_ai_do_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
if (err)
return 4;
- /* check channel/gain list against card's limitations */
- if (cmd->chanlist) {
- unsigned int chan = CR_CHAN(cmd->chanlist[0]);
- unsigned int range = CR_RANGE(cmd->chanlist[0]);
- unsigned int next;
- int i;
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- next = cmd->chanlist[i];
- if (CR_CHAN(next) != (chan + i) % N_CHAN_AI) {
- dev_err(dev->class_dev,
- "chanlist must be consecutive, counting upwards\n");
- err++;
- }
- if (CR_RANGE(next) != range) {
- dev_err(dev->class_dev,
- "chanlist must all have the same gain\n");
- err++;
- }
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= das800_ai_check_chanlist(dev, s, cmd);
if (err)
return 5;
if (async->cmd.convert_src == TRIG_TIMER) {
conv_bits |= CASC | ITE;
/* set conversion frequency */
- if (das800_set_frequency(dev) < 0) {
- comedi_error(dev, "Error setting up counters");
- return -1;
- }
+ das800_set_frequency(dev);
}
spin_lock_irqsave(&dev->spinlock, irq_flags);
static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- const struct das800_board *thisboard = comedi_board(dev);
+ const struct das800_board *thisboard;
struct das800_private *devpriv;
struct comedi_subdevice *s;
unsigned int irq = it->options[1];
return *ns;
}
+static int dmm32at_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
+ unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
+ int i;
+
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+ unsigned int range = CR_RANGE(cmd->chanlist[i]);
+
+ if (chan != (chan0 + i) % s->n_chan) {
+ dev_dbg(dev->class_dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ return -EINVAL;
+ }
+ if (range != range0) {
+ dev_dbg(dev->class_dev,
+ "entries in chanlist must all have the same gain\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int dmm32at_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
int err = 0;
int tmp;
- int start_chan, gain, i;
/* Step 1 : check if triggers are trivially valid */
if (err)
return 4;
- /* step 5 check the channel list, the channel list for this
- board must be consecutive and gains must be the same */
-
- if (cmd->chanlist) {
- gain = CR_RANGE(cmd->chanlist[0]);
- start_chan = CR_CHAN(cmd->chanlist[0]);
- for (i = 1; i < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i]) !=
- (start_chan + i) % s->n_chan) {
- comedi_error(dev,
- "entries in chanlist must be consecutive channels, counting upwards\n");
- err++;
- }
- if (CR_RANGE(cmd->chanlist[i]) != gain) {
- comedi_error(dev,
- "entries in chanlist must all have the same gain\n");
- err++;
- }
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= dmm32at_ai_check_chanlist(dev, s, cmd);
if (err)
return 5;
*/
static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- const struct dt2801_board *board = comedi_board(dev);
+ const struct dt2801_board *board;
struct dt2801_private *devpriv;
struct comedi_subdevice *s;
int board_code, type;
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 5000);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg, 2);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
if (cmd->stop_src == TRIG_COUNT) {
/* any count is allowed */
}
static int dt282x_ao_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int x)
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
struct dt282x_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
int size;
- if (x != 0)
+ if (trig_num != cmd->start_src)
return -EINVAL;
size = cfc_read_array_from_buffer(s, devpriv->dma[0].buf,
return 0;
}
+static int gsc_hpdi_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ int i;
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+
+ if (chan != i) {
+ dev_dbg(dev->class_dev,
+ "chanlist must be ch 0 to 31 in order\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int gsc_hpdi_cmd_test(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
int err = 0;
- int i;
if (s->io_bits)
return -EINVAL;
/* Step 3: check if arguments are trivially valid */
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+
if (!cmd->chanlist_len || !cmd->chanlist) {
cmd->chanlist_len = 32;
err |= -EINVAL;
if (err)
return 4;
- /* step 5: complain about special chanlist considerations */
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i]) != i) {
- /* XXX could support 8 or 16 channels */
- dev_err(dev->class_dev,
- "chanlist must be ch 0 to 31 in order");
- err |= -EINVAL;
- break;
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= gsc_hpdi_check_chanlist(dev, s, cmd);
if (err)
return 5;
return 0;
}
-static int ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
+static int me4000_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
- const struct me4000_board *thisboard = comedi_board(dev);
- int aref;
+ const struct me4000_board *board = comedi_board(dev);
+ unsigned int max_diff_chan = board->ai_diff_nchan;
+ unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
int i;
- /* Check whether a channel list is available */
- if (!cmd->chanlist_len) {
- dev_err(dev->class_dev, "No channel list available\n");
- return -EINVAL;
- }
-
- /* Check the channel list size */
- if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
- dev_err(dev->class_dev, "Channel list is to large\n");
- return -EINVAL;
- }
-
- /* Check the pointer */
- if (!cmd->chanlist) {
- dev_err(dev->class_dev, "NULL pointer to channel list\n");
- return -EFAULT;
- }
-
- /* Check whether aref is equal for all entries */
- aref = CR_AREF(cmd->chanlist[0]);
for (i = 0; i < cmd->chanlist_len; i++) {
- if (CR_AREF(cmd->chanlist[i]) != aref) {
- dev_err(dev->class_dev,
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+ unsigned int range = CR_RANGE(cmd->chanlist[i]);
+ unsigned int aref = CR_AREF(cmd->chanlist[i]);
+
+ if (aref != aref0) {
+ dev_dbg(dev->class_dev,
"Mode is not equal for all entries\n");
return -EINVAL;
}
- }
- /* Check whether channels are available for this ending */
- if (aref == SDF_DIFF) {
- for (i = 0; i < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i]) >=
- thisboard->ai_diff_nchan) {
- dev_err(dev->class_dev,
- "Channel number to high\n");
- return -EINVAL;
- }
- }
- } else {
- for (i = 0; i < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai_nchan) {
- dev_err(dev->class_dev,
+ if (aref == SDF_DIFF) {
+ if (chan >= max_diff_chan) {
+ dev_dbg(dev->class_dev,
"Channel number to high\n");
return -EINVAL;
}
- }
- }
- /* Check if bipolar is set for all entries when in differential mode */
- if (aref == SDF_DIFF) {
- for (i = 0; i < cmd->chanlist_len; i++) {
- if (CR_RANGE(cmd->chanlist[i]) != 1 &&
- CR_RANGE(cmd->chanlist[i]) != 2) {
- dev_err(dev->class_dev,
+ if (!comedi_range_is_bipolar(s, range)) {
+ dev_dbg(dev->class_dev,
"Bipolar is not selected in differential mode\n");
return -EINVAL;
}
err |= -EINVAL;
}
- if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) {
- } else if (cmd->stop_src == TRIG_COUNT &&
- cmd->scan_end_src == TRIG_NONE) {
- } else if (cmd->stop_src == TRIG_NONE &&
- cmd->scan_end_src == TRIG_COUNT) {
- } else if (cmd->stop_src == TRIG_COUNT &&
- cmd->scan_end_src == TRIG_COUNT) {
- } else {
- err |= -EINVAL;
- }
-
if (err)
return 2;
/* Step 3: check if arguments are trivially valid */
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+
if (cmd->chanlist_len < 1) {
cmd->chanlist_len = 1;
err |= -EINVAL;
if (err)
return 4;
- /*
- * Stage 5. Check the channel list.
- */
- if (ai_check_chanlist(dev, s, cmd))
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= me4000_ai_check_chanlist(dev, s, cmd);
+
+ if (err)
return 5;
return 0;
unsigned int *data)
{
struct me4000_info *info = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
int err;
switch (data[0]) {
if (insn->n != 1)
return -EINVAL;
- err = i8254_load(info->timer_regbase, 0, insn->chanspec, 0,
- I8254_MODE0 | I8254_BINARY);
+ err = i8254_set_mode(info->timer_regbase, 0, chan,
+ I8254_MODE0 | I8254_BINARY);
if (err)
return err;
+ i8254_write(info->timer_regbase, 0, chan, 0);
break;
case GPCT_SET_OPERATION:
if (insn->n != 2)
return -EINVAL;
- err = i8254_set_mode(info->timer_regbase, 0, insn->chanspec,
+ err = i8254_set_mode(info->timer_regbase, 0, chan,
(data[1] << 1) | I8254_BINARY);
if (err)
return err;
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
s->range_table = &range_digital;
s->insn_config = ni6527_intr_insn_config;
s->insn_bits = ni6527_intr_insn_bits;
+ s->len_chanlist = 1;
s->do_cmdtest = ni6527_intr_cmdtest;
s->do_cmd = ni6527_intr_cmd;
s->cancel = ni6527_intr_cancel;
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
s->n_chan = 1;
s->range_table = &range_unknown;
s->maxdata = 1;
+ s->len_chanlist = 1;
s->do_cmdtest = ni_65xx_intr_cmdtest;
s->do_cmd = ni_65xx_intr_cmd;
s->cancel = ni_65xx_intr_cancel;
return 0;
}
+static int a2150_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
+ unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
+ int i;
+
+ if (cmd->chanlist_len == 2 && (chan0 == 1 || chan0 == 3)) {
+ dev_dbg(dev->class_dev,
+ "length 2 chanlist must be channels 0,1 or channels 2,3\n");
+ return -EINVAL;
+ }
+
+ if (cmd->chanlist_len == 3) {
+ dev_dbg(dev->class_dev,
+ "chanlist must have 1,2 or 4 channels\n");
+ return -EINVAL;
+ }
+
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+ unsigned int aref = CR_AREF(cmd->chanlist[i]);
+
+ if (chan != (chan0 + i)) {
+ dev_dbg(dev->class_dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ return -EINVAL;
+ }
+
+ if (chan == 2)
+ aref0 = aref;
+ if (aref != aref0) {
+ dev_dbg(dev->class_dev,
+ "channels 0/1 and 2/3 must have the same analog reference\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int a2150_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
const struct a2150_board *thisboard = comedi_board(dev);
int err = 0;
int tmp;
- int startChan;
- int i;
/* Step 1 : check if triggers are trivially valid */
if (err)
return 4;
- /* check channel/gain list against card's limitations */
- if (cmd->chanlist) {
- startChan = CR_CHAN(cmd->chanlist[0]);
- for (i = 1; i < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
- comedi_error(dev,
- "entries in chanlist must be consecutive channels, counting upwards\n");
- err++;
- }
- }
- if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
- comedi_error(dev,
- "length 2 chanlist must be channels 0,1 or channels 2,3");
- err++;
- }
- if (cmd->chanlist_len == 3) {
- comedi_error(dev,
- "chanlist must have 1,2 or 4 channels");
- err++;
- }
- if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
- CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3])) {
- comedi_error(dev,
- "channels 0/1 and 2/3 must have the same analog reference");
- err++;
- }
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= a2150_ai_check_chanlist(dev, s, cmd);
if (err)
return 5;
struct a2150_private *devpriv = dev->private;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
+ unsigned long timer_base = dev->iobase + I8253_BASE_REG;
unsigned long lock_flags;
unsigned int old_config_bits = devpriv->config_bits;
unsigned int trigger_bits;
outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
/* may need to wait 72 sampling periods if timing was changed */
- i8254_load(dev->iobase + I8253_BASE_REG, 0, 2, 72, 0);
+ i8254_set_mode(timer_base, 0, 2, I8254_MODE0 | I8254_BINARY);
+ i8254_write(timer_base, 0, 2, 72);
/* setup start triggering */
trigger_bits = 0;
static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- const struct a2150_board *thisboard = comedi_board(dev);
+ const struct a2150_board *thisboard;
struct a2150_private *devpriv;
struct comedi_subdevice *s;
unsigned int irq = it->options[1];
static void atao_reset(struct comedi_device *dev)
{
struct atao_private *devpriv = dev->private;
+ unsigned long timer_base = dev->iobase + ATAO_82C53_BASE;
/* This is the reset sequence described in the manual */
outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
/* Put outputs of counter 1 and counter 2 in a high state */
- i8254_load(dev->iobase + ATAO_82C53_BASE, 0,
- 0, 0x0003, I8254_MODE4 | I8254_BINARY);
- i8254_set_mode(dev->iobase + ATAO_82C53_BASE, 0,
- 1, I8254_MODE4 | I8254_BINARY);
+ i8254_set_mode(timer_base, 0, 0, I8254_MODE4 | I8254_BINARY);
+ i8254_set_mode(timer_base, 0, 1, I8254_MODE4 | I8254_BINARY);
+ i8254_write(timer_base, 0, 0, 0x0003);
outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG);
};
#endif
-static int labpc_counter_load(struct comedi_device *dev,
- unsigned long base_address,
- unsigned int counter_number,
- unsigned int count, unsigned int mode)
+static void labpc_counter_load(struct comedi_device *dev,
+ unsigned long base_address,
+ unsigned int counter_number,
+ unsigned int count,
+ unsigned int mode)
{
const struct labpc_boardinfo *board = comedi_board(dev);
- if (board->has_mmio)
- return i8254_mm_load((void __iomem *)base_address, 0,
- counter_number, count, mode);
- else
- return i8254_load(base_address, 0, counter_number, count, mode);
+ if (board->has_mmio) {
+ void __iomem *mmio_base = (void __iomem *)base_address;
+
+ i8254_mm_set_mode(mmio_base, 0, counter_number, mode);
+ i8254_mm_write(mmio_base, 0, counter_number, count);
+ } else {
+ i8254_set_mode(base_address, 0, counter_number, mode);
+ i8254_write(base_address, 0, counter_number, count);
+ }
}
-static int labpc_counter_set_mode(struct comedi_device *dev,
- unsigned long base_address,
- unsigned int counter_number,
- unsigned int mode)
+static void labpc_counter_set_mode(struct comedi_device *dev,
+ unsigned long base_address,
+ unsigned int counter_number,
+ unsigned int mode)
{
const struct labpc_boardinfo *board = comedi_board(dev);
- if (board->has_mmio)
- return i8254_mm_set_mode((void __iomem *)base_address, 0,
- counter_number, mode);
- else
- return i8254_set_mode(base_address, 0, counter_number, mode);
+ if (board->has_mmio) {
+ void __iomem *mmio_base = (void __iomem *)base_address;
+
+ i8254_mm_set_mode(mmio_base, 0, counter_number, mode);
+ } else {
+ i8254_set_mode(base_address, 0, counter_number, mode);
+ }
}
static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
/* initialize pacer counter to prevent any problems */
- ret = labpc_counter_set_mode(dev, dev->iobase + COUNTER_A_BASE_REG,
- 0, I8254_MODE2);
- if (ret)
- return ret;
+ labpc_counter_set_mode(dev, dev->iobase + COUNTER_A_BASE_REG,
+ 0, I8254_MODE2);
labpc_clear_adc_fifo(dev);
return 0;
}
-static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
- const struct comedi_cmd *cmd,
- enum scan_mode mode)
+static int labpc_ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
- int channel, range, aref, i;
-
- if (cmd->chanlist == NULL)
- return 0;
+ enum scan_mode mode = labpc_ai_scan_mode(cmd);
+ unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
+ unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
+ unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
+ int i;
if (mode == MODE_SINGLE_CHAN)
return 0;
- if (mode == MODE_SINGLE_CHAN_INTERVAL) {
- if (cmd->chanlist_len > 0xff) {
- comedi_error(dev,
- "ni_labpc: chanlist too long for single channel interval mode\n");
- return 1;
- }
- }
-
- channel = CR_CHAN(cmd->chanlist[0]);
- range = CR_RANGE(cmd->chanlist[0]);
- aref = CR_AREF(cmd->chanlist[0]);
-
for (i = 0; i < cmd->chanlist_len; i++) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+ unsigned int range = CR_RANGE(cmd->chanlist[i]);
+ unsigned int aref = CR_AREF(cmd->chanlist[i]);
switch (mode) {
+ case MODE_SINGLE_CHAN:
+ break;
case MODE_SINGLE_CHAN_INTERVAL:
- if (CR_CHAN(cmd->chanlist[i]) != channel) {
- comedi_error(dev,
- "channel scanning order specified in chanlist is not supported by hardware.\n");
- return 1;
+ if (chan != chan0) {
+ dev_dbg(dev->class_dev,
+ "channel scanning order specified in chanlist is not supported by hardware\n");
+ return -EINVAL;
}
break;
case MODE_MULT_CHAN_UP:
- if (CR_CHAN(cmd->chanlist[i]) != i) {
- comedi_error(dev,
- "channel scanning order specified in chanlist is not supported by hardware.\n");
- return 1;
+ if (chan != i) {
+ dev_dbg(dev->class_dev,
+ "channel scanning order specified in chanlist is not supported by hardware\n");
+ return -EINVAL;
}
break;
case MODE_MULT_CHAN_DOWN:
- if (CR_CHAN(cmd->chanlist[i]) !=
- cmd->chanlist_len - i - 1) {
- comedi_error(dev,
- "channel scanning order specified in chanlist is not supported by hardware.\n");
- return 1;
+ if (chan != (cmd->chanlist_len - i - 1)) {
+ dev_dbg(dev->class_dev,
+ "channel scanning order specified in chanlist is not supported by hardware\n");
+ return -EINVAL;
}
break;
- default:
- dev_err(dev->class_dev,
- "ni_labpc: bug! in chanlist check\n");
- return 1;
- break;
}
- if (CR_RANGE(cmd->chanlist[i]) != range) {
- comedi_error(dev,
- "entries in chanlist must all have the same range\n");
- return 1;
+ if (range != range0) {
+ dev_dbg(dev->class_dev,
+ "entries in chanlist must all have the same range\n");
+ return -EINVAL;
}
- if (CR_AREF(cmd->chanlist[i]) != aref) {
- comedi_error(dev,
- "entries in chanlist must all have the same reference\n");
- return 1;
+ if (aref != aref0) {
+ dev_dbg(dev->class_dev,
+ "entries in chanlist must all have the same reference\n");
+ return -EINVAL;
}
}
/* Step 3: check if arguments are trivially valid */
- if (cmd->start_arg == TRIG_NOW)
+ switch (cmd->start_src) {
+ case TRIG_NOW:
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ break;
+ case TRIG_EXT:
+ /* start_arg value is ignored */
+ break;
+ }
if (!cmd->chanlist_len)
err |= -EINVAL;
if (err)
return 4;
- if (labpc_ai_chanlist_invalid(dev, cmd, mode))
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= labpc_ai_check_chanlist(dev, s, cmd);
+
+ if (err)
return 5;
return 0;
unsigned int aref = CR_AREF(chanspec);
enum transfer_type xfer;
unsigned long flags;
- int ret;
/* make sure board is disabled before setting up acquisition */
labpc_cancel(dev, s);
* load counter a1 with count of 3
* (pc+ manual says this is minimum allowed) using mode 0
*/
- ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
- 1, 3, I8254_MODE0);
+ labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
+ 1, 3, I8254_MODE0);
} else {
/* just put counter a1 in mode 0 to set its output low */
- ret = labpc_counter_set_mode(dev,
- dev->iobase + COUNTER_A_BASE_REG,
- 1, I8254_MODE0);
- }
- if (ret) {
- comedi_error(dev, "error loading counter a1");
- return ret;
+ labpc_counter_set_mode(dev, dev->iobase + COUNTER_A_BASE_REG,
+ 1, I8254_MODE0);
}
/* figure out what method we will use to transfer data */
/* set up pacing */
labpc_adc_timing(dev, cmd, mode);
/* load counter b0 in mode 3 */
- ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
- 0, devpriv->divisor_b0, I8254_MODE3);
- if (ret < 0) {
- comedi_error(dev, "error loading counter b0");
- return -1;
- }
+ labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
+ 0, devpriv->divisor_b0, I8254_MODE3);
}
/* set up conversion pacing */
if (labpc_ai_convert_period(cmd, mode)) {
/* load counter a0 in mode 2 */
- ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
- 0, devpriv->divisor_a0, I8254_MODE2);
+ labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
+ 0, devpriv->divisor_a0, I8254_MODE2);
} else {
/* initialize pacer counter to prevent any problems */
- ret = labpc_counter_set_mode(dev,
- dev->iobase + COUNTER_A_BASE_REG,
- 0, I8254_MODE2);
- }
- if (ret) {
- comedi_error(dev, "error loading counter a0");
- return ret;
+ labpc_counter_set_mode(dev, dev->iobase + COUNTER_A_BASE_REG,
+ 0, I8254_MODE2);
}
/* set up scan pacing */
if (labpc_ai_scan_period(cmd, mode)) {
/* load counter b1 in mode 2 */
- ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
- 1, devpriv->divisor_b1, I8254_MODE2);
- if (ret < 0) {
- comedi_error(dev, "error loading counter b1");
- return -1;
- }
+ labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
+ 1, devpriv->divisor_b1, I8254_MODE2);
}
labpc_clear_adc_fifo(dev);
const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
int err = 0;
- int tmp;
+ unsigned int tmp;
unsigned int sources;
/* Step 1 : check if triggers are trivially valid */
/* Step 3: check if arguments are trivially valid */
- if (cmd->start_src == TRIG_EXT) {
- /* external trigger */
- unsigned int tmp = CR_CHAN(cmd->start_arg);
+ switch (cmd->start_src) {
+ case TRIG_NOW:
+ case TRIG_INT:
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ break;
+ case TRIG_EXT:
+ tmp = CR_CHAN(cmd->start_arg);
if (tmp > 16)
tmp = 16;
tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
err |= cfc_check_trigger_arg_is(&cmd->start_arg, tmp);
- } else {
- /* true for both TRIG_NOW and TRIG_INT */
- err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ break;
}
if (cmd->scan_begin_src == TRIG_TIMER) {
}
#endif
- switch (cmd->start_src) {
- case TRIG_NOW:
+ if (cmd->start_src == TRIG_NOW) {
/* AI_START1_Pulse */
devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
AI_Command_2_Register);
s->async->inttrig = NULL;
- break;
- case TRIG_EXT:
+ } else if (cmd->start_src == TRIG_EXT) {
s->async->inttrig = NULL;
- break;
- case TRIG_INT:
- s->async->inttrig = &ni_ai_inttrig;
- break;
+ } else { /* TRIG_INT */
+ s->async->inttrig = ni_ai_inttrig;
}
return 0;
}
-static int ni_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum)
+static int ni_ai_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
struct ni_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
- if (trignum != 0)
+ if (trig_num != cmd->start_arg)
return -EINVAL;
devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
return -EINVAL;
}
-static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum)
+static int ni_ao_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
const struct ni_board_struct *board __maybe_unused = comedi_board(dev);
struct ni_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
int ret;
int interrupt_b_bits;
int i;
static const int timeout = 1000;
- if (trignum != 0)
+ if (trig_num != cmd->start_arg)
return -EINVAL;
/* Null trig at beginning prevent ao start trigger from executing more than
AO_BC_TC_Interrupt_Enable, 1);
}
- s->async->inttrig = &ni_ao_inttrig;
+ s->async->inttrig = ni_ao_inttrig;
return 0;
}
const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
int err = 0;
- int tmp;
+ unsigned int tmp;
/* Step 1 : check if triggers are trivially valid */
/* Step 3: check if arguments are trivially valid */
- if (cmd->start_src == TRIG_EXT) {
- /* external trigger */
- unsigned int tmp = CR_CHAN(cmd->start_arg);
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ break;
+ case TRIG_EXT:
+ tmp = CR_CHAN(cmd->start_arg);
if (tmp > 18)
tmp = 18;
tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
err |= cfc_check_trigger_arg_is(&cmd->start_arg, tmp);
- } else {
- /* true for both TRIG_NOW and TRIG_INT */
- err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ break;
}
if (cmd->scan_begin_src == TRIG_TIMER) {
if (err)
return 4;
- /* step 5: fix up chanlist */
-
- if (err)
- return 5;
-
return 0;
}
return insn->n;
}
+static int ni_cdio_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ int i;
+
+ for (i = 0; i < cmd->chanlist_len; ++i) {
+ unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+
+ if (chan != i)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int ni_cdio_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
int err = 0;
int tmp;
- unsigned i;
/* Step 1 : check if triggers are trivially valid */
if (err)
return 4;
- /* step 5: check chanlist */
-
- for (i = 0; i < cmd->chanlist_len; ++i) {
- if (cmd->chanlist[i] != i)
- err = 1;
- }
+ /* Step 5: check channel list if it exists */
+ if (cmd->chanlist && cmd->chanlist_len > 0)
+ err |= ni_cdio_check_chanlist(dev, s, cmd);
if (err)
return 5;
retval = ni_request_cdo_mite_channel(dev);
if (retval < 0)
return retval;
- s->async->inttrig = &ni_cdo_inttrig;
+
+ s->async->inttrig = ni_cdo_inttrig;
+
return 0;
}
-static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum)
+static int ni_cdo_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
#ifdef PCIDMA
struct ni_private *devpriv = dev->private;
unsigned long flags;
#endif
+ struct comedi_cmd *cmd = &s->async->cmd;
int retval = 0;
unsigned i;
const unsigned timeout = 1000;
+ if (trig_num != cmd->start_arg)
+ return -EINVAL;
+
s->async->inttrig = NULL;
/* read alloc the entire buffer */
}
static int ni_pcidio_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int trignum)
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
struct nidio96_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
- if (trignum != 0)
+ if (trig_num != cmd->start_arg)
return -EINVAL;
writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode);
static int ni_tio_input_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s,
- unsigned int trignum)
+ unsigned int trig_num)
{
+ struct ni_gpct *counter = s->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
unsigned long flags;
int retval = 0;
- struct ni_gpct *counter = s->private;
BUG_ON(counter == NULL);
- if (trignum != 0)
+
+ if (trig_num != cmd->start_src)
return -EINVAL;
spin_lock_irqsave(&counter->lock, flags);
/* Step 3: check if arguments are trivially valid */
- if (cmd->start_src != TRIG_EXT)
+ switch (cmd->start_src) {
+ case TRIG_NOW:
+ case TRIG_INT:
+ case TRIG_OTHER:
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ break;
+ case TRIG_EXT:
+ /* start_arg is the start_trigger passed to ni_tio_arm() */
+ break;
+ }
if (cmd->scan_begin_src != TRIG_EXT)
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
return 0;
}
+static void pcl711_ai_load_counters(struct comedi_device *dev)
+{
+ struct pcl711_private *devpriv = dev->private;
+ unsigned long timer_base = dev->iobase + PCL711_TIMER_BASE;
+
+ i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
+ i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
+
+ i8254_write(timer_base, 0, 1, devpriv->divisor1);
+ i8254_write(timer_base, 0, 2, devpriv->divisor2);
+}
+
static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct pcl711_private *devpriv = dev->private;
}
if (cmd->scan_begin_src == TRIG_TIMER) {
- i8254_load(dev->iobase + PCL711_TIMER_BASE, 0,
- 1, devpriv->divisor1, I8254_MODE2 | I8254_BINARY);
- i8254_load(dev->iobase + PCL711_TIMER_BASE, 0,
- 2, devpriv->divisor2, I8254_MODE2 | I8254_BINARY);
-
+ pcl711_ai_load_counters(dev);
outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG);
-
pcl711_ai_set_mode(dev, PCL711_MODE_PACER_IRQ);
} else {
pcl711_ai_set_mode(dev, PCL711_MODE_EXT_IRQ);
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (err)
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = pcl726_intr_insn_bits;
+ s->len_chanlist = 1;
s->do_cmdtest = pcl726_intr_cmdtest;
s->do_cmd = pcl726_intr_cmd;
s->cancel = pcl726_intr_cancel;
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= cfc_check_trigger_arg_max(&cmd->chanlist_len, MAX_CHANLIST_LEN);
err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
if (cmd->stop_src == TRIG_COUNT)
devpriv->ai_dma = 0;
break;
}
- } else
+ } else {
devpriv->ai_dma = 0;
+ }
devpriv->ai_act_scan = 0;
devpriv->ai_poll_ptr = 0;
return 0;
}
-/*
- * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
- */
-static int
-pcmmio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum)
+static int pcmmio_inttrig_start_intr(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
struct pcmmio_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
unsigned long flags;
int event = 0;
- if (trignum != 0)
+ if (trig_num != cmd->start_arg)
return -EINVAL;
spin_lock_irqsave(&devpriv->spinlock, flags);
}
/* Set up start of acquisition. */
- switch (cmd->start_src) {
- case TRIG_INT:
+ if (cmd->start_src == TRIG_INT)
s->async->inttrig = pcmmio_inttrig_start_intr;
- break;
- default:
- /* TRIG_NOW */
+ else /* TRIG_NOW */
event = pcmmio_start_intr(dev, s);
- break;
- }
+
spin_unlock_irqrestore(&devpriv->spinlock, flags);
if (event)
return 0;
}
-/*
- * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
- */
-static int
-pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum)
+static int pcmuio_inttrig_start_intr(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
struct pcmuio_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
int asic = pcmuio_subdevice_to_asic(s);
struct pcmuio_asic *chip = &devpriv->asics[asic];
unsigned long flags;
int event = 0;
- if (trignum != 0)
+ if (trig_num != cmd->start_arg)
return -EINVAL;
spin_lock_irqsave(&chip->spinlock, flags);
}
/* Set up start of acquisition. */
- switch (cmd->start_src) {
- case TRIG_INT:
+ if (cmd->start_src == TRIG_INT)
s->async->inttrig = pcmuio_inttrig_start_intr;
- break;
- default:
- /* TRIG_NOW */
+ else /* TRIG_NOW */
event = pcmuio_start_intr(dev, s);
- break;
- }
+
spin_unlock_irqrestore(&chip->spinlock, flags);
if (event)
err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9);
}
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
if (cmd->stop_src == TRIG_COUNT) {
/* TODO check for rounding error due to counter wrap */
} else {
/* step 4: fix up any arguments */
- if (cmd->chanlist_len > RTD_MAX_CHANLIST) {
- cmd->chanlist_len = RTD_MAX_CHANLIST;
- err++;
- }
if (cmd->scan_begin_src == TRIG_TIMER) {
tmp = cmd->scan_begin_arg;
rtd_ns_to_timer(&cmd->scan_begin_arg,
/* ************** EEPROM ACCESS FUNCTIONS ************** */
-static uint32_t s626_i2c_handshake(struct comedi_device *dev, uint32_t val)
+static int s626_i2c_handshake_eoc(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned long context)
+{
+ bool status;
+
+ status = s626_mc_test(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
+ if (status)
+ return 0;
+ return -EBUSY;
+}
+
+static int s626_i2c_handshake(struct comedi_device *dev, uint32_t val)
{
struct s626_private *devpriv = dev->private;
unsigned int ctrl;
+ int ret;
/* Write I2C command to I2C Transfer Control shadow register */
writel(val, devpriv->mmio + S626_P_I2CCTRL);
* wait for upload confirmation.
*/
s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
- while (!s626_mc_test(dev, S626_MC2_UPLD_IIC, S626_P_MC2))
- ;
+ ret = comedi_timeout(dev, NULL, NULL, s626_i2c_handshake_eoc, 0);
+ if (ret)
+ return ret;
/* Wait until I2C bus transfer is finished or an error occurs */
do {
/* Wait for the data to arrive in FB BUFFER 1 register. */
/* Wait for ADC done */
- while (!(readl(devpriv->mmio + S626_P_PSR) & S626_PSR_GPIO2))
- ;
+ ret = comedi_timeout(dev, s, insn, s626_ai_eoc, 0);
+ if (ret)
+ return ret;
/* Fetch ADC data from audio interface's input shift register. */
}
static int s626_ai_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int trignum)
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
- if (trignum != 0)
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (trig_num != cmd->start_arg)
return -EINVAL;
/* Start executing the RPS program */
if (err)
return 2;
- /* step 3: make sure arguments are trivially compatible */
+ /* Step 3: check if arguments are trivially valid */
- if (cmd->start_src != TRIG_EXT)
+ switch (cmd->start_src) {
+ case TRIG_NOW:
+ case TRIG_INT:
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- if (cmd->start_src == TRIG_EXT)
+ break;
+ case TRIG_EXT:
err |= cfc_check_trigger_arg_max(&cmd->start_arg, 39);
+ break;
+ }
+
if (cmd->scan_begin_src == TRIG_EXT)
err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 39);
if (cmd->convert_src == TRIG_EXT)
writel(S626_I2C_CLKSEL | S626_I2C_ABORT,
devpriv->mmio + S626_P_I2CSTAT);
s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
- while (!(readl(devpriv->mmio + S626_P_MC2) & S626_MC2_UPLD_IIC))
- ;
+ ret = comedi_timeout(dev, NULL, NULL, s626_i2c_handshake_eoc, 0);
+ if (ret)
+ return ret;
/*
* Per SAA7146 data sheet, write to STATUS
for (i = 0; i < 2; i++) {
writel(S626_I2C_CLKSEL, devpriv->mmio + S626_P_I2CSTAT);
s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
- while (!s626_mc_test(dev, S626_MC2_UPLD_IIC, S626_P_MC2))
- ;
+ ret = comedi_timeout(dev, NULL, NULL, s626_i2c_handshake_eoc, 0);
+ if (ret)
+ return ret;
}
/*
/* pointer to the DA */
*datap++ = val & 0xff;
*datap++ = (val >> 8) & 0xff;
- *datap++ = chan;
+ *datap++ = chan << 6;
devpriv->ao_readback[chan] = val;
s->async->events |= COMEDI_CB_BLOCK;
static int usbdux_ai_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s,
- unsigned int trignum)
+ unsigned int trig_num)
{
struct usbdux_private *devpriv = dev->private;
- int ret = -EINVAL;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int ret;
- down(&devpriv->sem);
+ if (trig_num != cmd->start_arg)
+ return -EINVAL;
- if (trignum != 0)
- goto ai_trig_exit;
+ down(&devpriv->sem);
if (!devpriv->ai_cmd_running) {
devpriv->ai_cmd_running = 1;
static int usbdux_ao_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s,
- unsigned int trignum)
+ unsigned int trig_num)
{
struct usbdux_private *devpriv = dev->private;
- int ret = -EINVAL;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int ret;
- down(&devpriv->sem);
+ if (trig_num != cmd->start_arg)
+ return -EINVAL;
- if (trignum != 0)
- goto ao_trig_exit;
+ down(&devpriv->sem);
if (!devpriv->ao_cmd_running) {
devpriv->ao_cmd_running = 1;
/* set current channel of the running acquisition to zero */
s->async->cur_chan = 0;
- for (i = 0; i < cmd->chanlist_len; ++i) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
-
- devpriv->ao_chanlist[i] = chan << 6;
- }
+ for (i = 0; i < cmd->chanlist_len; ++i)
+ devpriv->ao_chanlist[i] = CR_CHAN(cmd->chanlist[i]);
/* we count in steps of 1ms (125us) */
/* 125us mode not used yet */
/* Step 3: check if arguments are trivially valid */
- if (cmd->start_src == TRIG_NOW)
- err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
if (!cmd->chanlist_len)
err |= -EINVAL;
static int usbduxfast_ai_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s,
- unsigned int trignum)
+ unsigned int trig_num)
{
struct usbduxfast_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
int ret;
if (!devpriv)
return -EFAULT;
+ if (trig_num != cmd->start_arg)
+ return -EINVAL;
+
down(&devpriv->sem);
- if (trignum != 0) {
- dev_err(dev->class_dev, "invalid trignum\n");
- up(&devpriv->sem);
- return -EINVAL;
- }
if (!devpriv->ai_cmd_running) {
devpriv->ai_cmd_running = 1;
ret = usbduxfast_submit_urb(dev);
return ret;
}
s->async->inttrig = NULL;
- } else {
- /*
- * TRIG_INT
- * don't enable the acquision operation
- * wait for an internal signal
- */
+ } else { /* TRIG_INT */
s->async->inttrig = usbduxfast_ai_inttrig;
}
up(&devpriv->sem);
static int usbduxsigma_ai_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s,
- unsigned int trignum)
+ unsigned int trig_num)
{
struct usbduxsigma_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
int ret;
- if (trignum != 0)
+ if (trig_num != cmd->start_arg)
return -EINVAL;
down(&devpriv->sem);
}
s->async->inttrig = NULL;
} else { /* TRIG_INT */
- /* wait for an internal signal and submit the urbs later */
s->async->inttrig = usbduxsigma_ai_inttrig;
}
static int usbduxsigma_ao_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s,
- unsigned int trignum)
+ unsigned int trig_num)
{
struct usbduxsigma_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
int ret;
- if (trignum != 0)
+ if (trig_num != cmd->start_arg)
return -EINVAL;
down(&devpriv->sem);
}
s->async->inttrig = NULL;
} else { /* TRIG_INT */
- /* wait for an internal signal and submit the urbs later */
s->async->inttrig = usbduxsigma_ao_inttrig;
}
static irqreturn_t chd_dec_isr(int irq, void *arg)
{
- struct crystalhd_adp *adp = (struct crystalhd_adp *) arg;
+ struct crystalhd_adp *adp = arg;
int rc = 0;
if (adp)
rc = crystalhd_cmd_interrupt(&adp->cmds);
}
static inline int crystalhd_user_data(void __user *ud, void *dr,
- int size, int set)
+ int size, int set)
{
int rc;
}
static int chd_dec_fetch_cdata(struct crystalhd_adp *adp,
- struct crystalhd_ioctl_data *io, uint32_t m_sz, unsigned long ua)
+ struct crystalhd_ioctl_data *io, uint32_t m_sz,
+ unsigned long ua)
{
unsigned long ua_off;
int rc = 0;
io->add_cdata_sz = m_sz;
ua_off = ua + sizeof(io->udata);
rc = crystalhd_user_data((void __user *)ua_off, io->add_cdata,
- io->add_cdata_sz, 0);
+ io->add_cdata_sz, 0);
if (rc) {
BCMLOG_ERR("failed to pull add_cdata sz:%x ua_off:%x\n",
io->add_cdata_sz, (unsigned int)ua_off);
}
static int chd_dec_release_cdata(struct crystalhd_adp *adp,
- struct crystalhd_ioctl_data *io, unsigned long ua)
+ struct crystalhd_ioctl_data *io,
+ unsigned long ua)
{
unsigned long ua_off;
int rc;
if (io->cmd != BCM_IOC_FW_DOWNLOAD) {
ua_off = ua + sizeof(io->udata);
rc = crystalhd_user_data((void __user *)ua_off, io->add_cdata,
- io->add_cdata_sz, 1);
+ io->add_cdata_sz, 1);
if (rc) {
BCMLOG_ERR(
"failed to push add_cdata sz:%x ua_off:%x\n",
}
rc = crystalhd_user_data((void __user *)ua, &io->udata,
- sizeof(io->udata), set);
+ sizeof(io->udata), set);
if (rc) {
BCMLOG_ERR("failed to %s iodata\n", (set ? "set" : "get"));
return rc;
}
dev = device_create(crystalhd_class, NULL,
- MKDEV(adp->chd_dec_major, 0), NULL, "crystalhd");
+ MKDEV(adp->chd_dec_major, 0), NULL, "crystalhd");
if (IS_ERR(dev)) {
rc = PTR_ERR(dev);
BCMLOG_ERR("failed to create device\n");
/* Allocate general purpose ioctl pool. */
for (i = 0; i < CHD_IODATA_POOL_SZ; i++) {
- temp = kzalloc(sizeof(struct crystalhd_ioctl_data),
- GFP_KERNEL);
+ temp = kzalloc(sizeof(*temp), GFP_KERNEL);
if (!temp) {
BCMLOG_ERR("ioctl data pool kzalloc failed\n");
rc = -ENOMEM;
enum BC_STATUS sts = BC_STS_SUCCESS;
BCMLOG(BCMLOG_DBG,
- "PCI_INFO: Vendor:0x%04x Device:0x%04x s_vendor:0x%04x s_device: 0x%04x\n",
- pdev->vendor, pdev->device, pdev->subsystem_vendor,
- pdev->subsystem_device);
+ "PCI_INFO: Vendor:0x%04x Device:0x%04x s_vendor:0x%04x s_device: 0x%04x\n",
+ pdev->vendor, pdev->device, pdev->subsystem_vendor,
+ pdev->subsystem_device);
- pinfo = kzalloc(sizeof(struct crystalhd_adp), GFP_KERNEL);
+ pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
if (!pinfo) {
BCMLOG_ERR("Failed to allocate memory\n");
return -ENOMEM;
hi->ndev = NULL;
hi->addr[0] = 0L;
hi->addr[1] = 0L;
- hi->addr_mapped[0] = 0L;
- hi->addr_mapped[1] = 0L;
+ hi->addr_mapped[0] = NULL;
+ hi->addr_mapped[1] = NULL;
}
}
if (hi->pci_slot == 0xff)
break;
if (hi->addr_mapped[0]) {
- iounmap((void *)(hi->addr_mapped[0]));
+ iounmap(hi->addr_mapped[0]);
release_mem_region((long) hi->addr[0], hi->len[0]);
- hi->addr_mapped[0] = 0;
+ hi->addr_mapped[0] = NULL;
}
if (hi->addr_mapped[1]) {
- iounmap((void *)(hi->addr_mapped[1]));
+ iounmap(hi->addr_mapped[1]);
release_mem_region((long) hi->addr[1], hi->len[1]);
- hi->addr_mapped[1] = 0;
+ hi->addr_mapped[1] = NULL;
}
}
}
#ifdef CONFIG_SBE_PMCC4_NCOMM
free_irq(hi->pdev[1]->irq, hi->ndev);
#endif
- OS_kfree(hi->ndev);
+ kfree(hi->ndev);
}
}
return -ENOMEM;
}
- hi->addr_mapped[j] = (unsigned long)ioremap(hi->addr[j], hi->len[j]);
+ hi->addr_mapped[j] = ioremap(hi->addr[j], hi->len[j]);
if (!hi->addr_mapped[j]) {
pr_warning("%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n",
hi->devname, hi->addr[j], hi->len[j]);
void musycc_wq_chan_restart(void *);
status_t __init c4_init(ci_t *, u_char *, u_char *);
status_t __init c4_init2(ci_t *);
-ci_t *__init c4_new(void *);
int __init c4hw_attach_all(void);
void __init hdw_sn_get(hdw_info_t *, int);
struct c4_priv *priv;
/* allocate then fill in private data structure */
- priv = OS_kmalloc(sizeof(struct c4_priv));
+ priv = kzalloc(sizeof(struct c4_priv), GFP_KERNEL);
if (!priv) {
pr_warning("%s: no memory for net_device !\n",
ci->devname);
if (!dev) {
pr_warning("%s: no memory for hdlc_device !\n",
ci->devname);
- OS_kfree(priv);
+ kfree(priv);
return NULL;
}
priv->ci = ci;
if (register_netdev(ndev) ||
(c4_init(ci, (u_char *) f0, (u_char *) f1) != SBE_DRVR_SUCCESS)) {
- OS_kfree(netdev_priv(ndev));
- OS_kfree(ndev);
+ kfree(netdev_priv(ndev));
+ kfree(ndev);
error_flag = -ENODEV;
return NULL;
}
pr_warning("%s: MUSYCC could not get irq: %d\n",
ndev->name, irq0);
unregister_netdev(ndev);
- OS_kfree(netdev_priv(ndev));
- OS_kfree(ndev);
+ kfree(netdev_priv(ndev));
+ kfree(ndev);
error_flag = -EIO;
return NULL;
}
pr_warning("%s: EBUS could not get irq: %d\n", hi->devname, irq1);
unregister_netdev(ndev);
free_irq(irq0, ndev);
- OS_kfree(netdev_priv(ndev));
- OS_kfree(ndev);
+ kfree(netdev_priv(ndev));
+ kfree(ndev);
error_flag = -EIO;
return NULL;
}
unregister_netdev(ndev);
free_irq(irq1, ndev);
free_irq(irq0, ndev);
- OS_kfree(netdev_priv(ndev));
- OS_kfree(ndev);
+ kfree(netdev_priv(ndev));
+ kfree(ndev);
/* failure, error_flag is set */
return NULL;
}
#define INT_QUEUE_BOUNDARY 4
- regaddr = OS_kmalloc((INT_QUEUE_SIZE + 1) * sizeof(u_int32_t));
+ regaddr = kzalloc((INT_QUEUE_SIZE + 1) * sizeof(u_int32_t),
+ GFP_KERNEL | GFP_DMA);
if (!regaddr)
return -ENOMEM;
ci->iqd_p_saved = regaddr; /* save orig value for free's usage */
#define GROUP_BOUNDARY 0x800
- regaddr = OS_kmalloc(sizeof(struct musycc_groupr) + GROUP_BOUNDARY);
+ regaddr = kzalloc(sizeof(struct musycc_groupr) + GROUP_BOUNDARY,
+ GFP_KERNEL | GFP_DMA);
if (!regaddr) {
for (gchan = 0; gchan < i; gchan++) {
pi = &ci->port[gchan];
- OS_kfree(pi->reg);
+ kfree(pi->reg);
pi->reg = NULL;
}
return -ENOMEM;
if (ch->mdr[i].mem_token)
OS_mem_token_free(ch->mdr[i].mem_token);
- OS_kfree(ch->mdr);
+ kfree(ch->mdr);
ch->mdr = NULL;
ch->rxd_num = 0;
- OS_kfree(ch->mdt);
+ kfree(ch->mdt);
ch->mdt = NULL;
ch->txd_num = 0;
#include "sbecom_inline_linux.h"
#include "pmcc4.h"
#include "sbe_promformat.h"
+#include "pmc93x6_eeprom.h"
#ifndef TRUE
#define TRUE 1
* using.
*/
-#define EE_MFG (long)0 /* Index to manufacturing record */
-#define EE_FIRST 0x28 /* Index to start testing at */
-#define EE_LIMIT 128 /* Index to end testing at */
-
+#define EE_MFG (long)0 /* Index to manufacturing record */
+#define EE_FIRST 0x28 /* Index to start testing at */
+#define EE_LIMIT 128 /* Index to end testing at */
/* Bit Ordering for Instructions
-**
-** A0, A1, A2, A3, A4, A5, A6, OP0, OP1, SB (lsb, or 1st bit out)
-**
-*/
-
-#define EPROM_EWEN 0x0019 /* Erase/Write enable (reversed) */
-#define EPROM_EWDS 0x0001 /* Erase/Write disable (reversed) */
-#define EPROM_READ 0x0003 /* Read (reversed) */
-#define EPROM_WRITE 0x0005 /* Write (reversed) */
-#define EPROM_ERASE 0x0007 /* Erase (reversed) */
-#define EPROM_ERAL 0x0009 /* Erase All (reversed) */
-#define EPROM_WRAL 0x0011 /* Write All (reversed) */
-
-#define EPROM_ADR_SZ 7 /* Number of bits in offset address */
-#define EPROM_OP_SZ 3 /* Number of bits in command */
-#define SIZE_ADDR_OP (EPROM_ADR_SZ + EPROM_OP_SZ)
-#define LC46A_MAX_OPS 10 /* Number of bits in Instruction */
-#define NUM_OF_BITS 8 /* Number of bits in data */
+ *
+ * A0, A1, A2, A3, A4, A5, A6, OP0, OP1, SB (lsb, or 1st bit out)
+ *
+ */
+#define EPROM_EWEN 0x0019 /* Erase/Write enable (reversed) */
+#define EPROM_EWDS 0x0001 /* Erase/Write disable (reversed) */
+#define EPROM_READ 0x0003 /* Read (reversed) */
+#define EPROM_WRITE 0x0005 /* Write (reversed) */
+#define EPROM_ERASE 0x0007 /* Erase (reversed) */
+#define EPROM_ERAL 0x0009 /* Erase All (reversed) */
+#define EPROM_WRAL 0x0011 /* Write All (reversed) */
-/* EEPROM signal bits */
-#define EPROM_ACTIVE_OUT_BIT 0x0001 /* Out data bit */
-#define EPROM_ACTIVE_IN_BIT 0x0002 /* In data bit */
-#define ACTIVE_IN_BIT_SHIFT 0x0001 /* Shift In data bit to LSB */
-#define EPROM_ENCS 0x0004 /* Set EEPROM CS during operation */
+#define EPROM_ADR_SZ 7 /* Number of bits in offset address */
+#define EPROM_OP_SZ 3 /* Number of bits in command */
+#define SIZE_ADDR_OP (EPROM_ADR_SZ + EPROM_OP_SZ)
+#define LC46A_MAX_OPS 10 /* Number of bits in Instruction */
+#define NUM_OF_BITS 8 /* Number of bits in data */
+/* EEPROM signal bits */
+#define EPROM_ACTIVE_OUT_BIT 0x0001 /* Out data bit */
+#define EPROM_ACTIVE_IN_BIT 0x0002 /* In data bit */
+#define ACTIVE_IN_BIT_SHIFT 0x0001 /* Shift In data bit to LSB */
+#define EPROM_ENCS 0x0004 /* Set EEPROM CS during operation */
/*------------------------------------------------------------------------
* The ByteReverse table is used to reverses the 8 bits within a byte
*/
static unsigned char ByteReverse[256];
-static int ByteReverseBuilt = FALSE;
-
+static int ByteReverseBuilt = FALSE;
/*------------------------------------------------------------------------
* mfg_template - initial serial EEPROM data structure
*------------------------------------------------------------------------
*/
-static u8 mfg_template[sizeof(FLD_TYPE2)] =
-{
- PROM_FORMAT_TYPE2, /* type; */
- 0x00, 0x1A, /* length[2]; */
- 0x00, 0x00, 0x00, 0x00, /* Crc32[4]; */
- 0x11, 0x76, /* Id[2]; */
- 0x07, 0x05, /* SubId[2] E1; */
- 0x00, 0xA0, 0xD6, 0x00, 0x00, 0x00, /* Serial[6]; */
- 0x00, 0x00, 0x00, 0x00, /* CreateTime[4]; */
- 0x00, 0x00, 0x00, 0x00, /* HeatRunTime[4]; */
- 0x00, 0x00, 0x00, 0x00, /* HeatRunIterations[4]; */
- 0x00, 0x00, 0x00, 0x00, /* HeatRunErrors[4]; */
+static u8 mfg_template[sizeof(FLD_TYPE2)] = {
+ PROM_FORMAT_TYPE2, /* type; */
+ 0x00, 0x1A, /* length[2]; */
+ 0x00, 0x00, 0x00, 0x00, /* Crc32[4]; */
+ 0x11, 0x76, /* Id[2]; */
+ 0x07, 0x05, /* SubId[2] E1; */
+ 0x00, 0xA0, 0xD6, 0x00, 0x00, 0x00, /* Serial[6]; */
+ 0x00, 0x00, 0x00, 0x00, /* CreateTime[4]; */
+ 0x00, 0x00, 0x00, 0x00, /* HeatRunTime[4]; */
+ 0x00, 0x00, 0x00, 0x00, /* HeatRunIterations[4]; */
+ 0x00, 0x00, 0x00, 0x00, /* HeatRunErrors[4]; */
};
-
/*------------------------------------------------------------------------
* BuildByteReverse - build the 8-bit reverse table
*------------------------------------------------------------------------
* (the MSB becomes the LSB etc.).
*/
-static void
-BuildByteReverse (void)
+static void BuildByteReverse(void)
{
- long half; /* Used to build by powers to 2 */
- int i;
+ /* Used to build by powers to 2 */
+ long half;
+ int i;
- ByteReverse[0] = 0;
+ ByteReverse[0] = 0;
- for (half = 1; half < sizeof (ByteReverse); half <<= 1)
- for (i = 0; i < half; i++)
- ByteReverse[half + i] = (char) (ByteReverse[i] | (0x80 / half));
+ for (half = 1; half < sizeof(ByteReverse); half <<= 1)
+ for (i = 0; i < half; i++)
+ ByteReverse[half + i] =
+ (char)(ByteReverse[i] | (0x80 / half));
- ByteReverseBuilt = TRUE;
+ ByteReverseBuilt = TRUE;
}
-
/*------------------------------------------------------------------------
* eeprom_delay - small delay for EEPROM timing
*------------------------------------------------------------------------
*/
-static void
-eeprom_delay (void)
+static void eeprom_delay(void)
{
- int timeout;
+ int timeout;
- for (timeout = 20; timeout; --timeout)
- {
- OS_uwait_dummy ();
- }
+ for (timeout = 20; timeout; --timeout)
+ OS_uwait_dummy();
}
-
/*------------------------------------------------------------------------
* eeprom_put_byte - Send a byte to the EEPROM serially
*------------------------------------------------------------------------
* the data to the EEPROM.
*/
-void
-eeprom_put_byte (long addr, long data, int count)
+static void eeprom_put_byte(long addr, long data, int count)
{
- u_int32_t output;
-
- while (--count >= 0)
- {
- output = (data & EPROM_ACTIVE_OUT_BIT) ? 1 : 0; /* Get next data bit */
- output |= EPROM_ENCS; /* Add Chip Select */
- data >>= 1;
-
- eeprom_delay ();
- pci_write_32 ((u_int32_t *) addr, output); /* Output it */
- }
+ u_int32_t output;
+
+ while (--count >= 0) {
+ /* Get next data bit */
+ output = (data & EPROM_ACTIVE_OUT_BIT) ? 1 : 0;
+ /* Add Chip Select */
+ output |= EPROM_ENCS;
+ data >>= 1;
+
+ eeprom_delay();
+ /* Output it */
+ pci_write_32((u_int32_t *) addr, output);
+ }
}
-
/*------------------------------------------------------------------------
* eeprom_get_byte - Receive a byte from the EEPROM serially
*------------------------------------------------------------------------
* from the EEPROM.
*/
-u_int32_t
-eeprom_get_byte (long addr)
+static u_int32_t eeprom_get_byte(long addr)
{
- u_int32_t input;
- u_int32_t data;
- int count;
+ u_int32_t input;
+ u_int32_t data;
+ int count;
/* Start the Reading of DATA
-**
-** The first read is a dummy as the data is latched in the
-** EPLD and read on the next read access to the EEPROM.
-*/
+ *
+ * The first read is a dummy as the data is latched in the
+ * EPLD and read on the next read access to the EEPROM.
+ */
- input = pci_read_32 ((u_int32_t *) addr);
+ input = pci_read_32((u_int32_t *) addr);
- data = 0;
- count = NUM_OF_BITS;
- while (--count >= 0)
- {
- eeprom_delay ();
- input = pci_read_32 ((u_int32_t *) addr);
+ data = 0;
+ count = NUM_OF_BITS;
+ while (--count >= 0) {
+ eeprom_delay();
+ input = pci_read_32((u_int32_t *) addr);
- data <<= 1; /* Shift data over */
- data |= (input & EPROM_ACTIVE_IN_BIT) ? 1 : 0;
+ /* Shift data over */
+ data <<= 1;
+ data |= (input & EPROM_ACTIVE_IN_BIT) ? 1 : 0;
- }
+ }
- return data;
+ return data;
}
-
/*------------------------------------------------------------------------
* disable_pmc_eeprom - Disable writes to the EEPROM
*------------------------------------------------------------------------
* Issue the EEPROM command to disable writes.
*/
-static void
-disable_pmc_eeprom (long addr)
+static void disable_pmc_eeprom(long addr)
{
- eeprom_put_byte (addr, EPROM_EWDS, SIZE_ADDR_OP);
+ eeprom_put_byte(addr, EPROM_EWDS, SIZE_ADDR_OP);
- pci_write_32 ((u_int32_t *) addr, 0); /* this removes Chip Select
- * from EEPROM */
+ /* this removes Chip Select from EEPROM */
+ pci_write_32((u_int32_t *) addr, 0);
}
-
/*------------------------------------------------------------------------
* enable_pmc_eeprom - Enable writes to the EEPROM
*------------------------------------------------------------------------
* Issue the EEPROM command to enable writes.
*/
-static void
-enable_pmc_eeprom (long addr)
+static void enable_pmc_eeprom(long addr)
{
- eeprom_put_byte (addr, EPROM_EWEN, SIZE_ADDR_OP);
+ eeprom_put_byte(addr, EPROM_EWEN, SIZE_ADDR_OP);
- pci_write_32 ((u_int32_t *) addr, 0); /* this removes Chip Select
- * from EEPROM */
+ /* this removes Chip Select from EEPROM */
+ pci_write_32((u_int32_t *) addr, 0);
}
-
/*------------------------------------------------------------------------
* pmc_eeprom_read - EEPROM location read
*------------------------------------------------------------------------
* the contents of the specified location to the calling routine.
*/
-u_int32_t
-pmc_eeprom_read (long addr, long mem_offset)
+static u_int32_t pmc_eeprom_read(long addr, long mem_offset)
{
- u_int32_t data; /* Data from chip */
+ /* Data from chip */
+ u_int32_t data;
- if (!ByteReverseBuilt)
- BuildByteReverse ();
+ if (!ByteReverseBuilt)
+ BuildByteReverse();
- mem_offset = ByteReverse[0x7F & mem_offset]; /* Reverse address */
- /*
- * NOTE: The max offset address is 128 or half the reversal table. So the
- * LSB is always zero and counts as a built in shift of one bit. So even
- * though we need to shift 3 bits to make room for the command, we only
- * need to shift twice more because of the built in shift.
- */
- mem_offset <<= 2; /* Shift for command */
- mem_offset |= EPROM_READ; /* Add command */
+ /* Reverse address */
+ mem_offset = ByteReverse[0x7F & mem_offset];
- eeprom_put_byte (addr, mem_offset, SIZE_ADDR_OP); /* Output chip address */
+ /*
+ * NOTE: The max offset address is 128 or half the reversal table. So
+ * the LSB is always zero and counts as a built in shift of one bit.
+ * So even though we need to shift 3 bits to make room for the command,
+ * we only need to shift twice more because of the built in shift.
+ */
- data = eeprom_get_byte (addr); /* Read chip data */
+ /* Shift for command */
+ mem_offset <<= 2;
+ /* Add command */
+ mem_offset |= EPROM_READ;
- pci_write_32 ((u_int32_t *) addr, 0); /* Remove Chip Select from
- * EEPROM */
+ /* Output chip address */
+ eeprom_put_byte(addr, mem_offset, SIZE_ADDR_OP);
- return (data & 0x000000FF);
-}
+ /* Read chip data */
+ data = eeprom_get_byte(addr);
+
+ /* Remove Chip Select from EEPROM */
+ pci_write_32((u_int32_t *) addr, 0);
+ return (data & 0x000000FF);
+}
/*------------------------------------------------------------------------
* pmc_eeprom_write - EEPROM location write
* operation succeeded.
*/
-int
-pmc_eeprom_write (long addr, long mem_offset, u_int32_t data)
+static int pmc_eeprom_write(long addr, long mem_offset, u_int32_t data)
{
- volatile u_int32_t temp;
- int count;
+ u_int32_t temp;
+ int count;
+
+ if (!ByteReverseBuilt)
+ BuildByteReverse();
+
+ /* Reverse address */
+ mem_offset = ByteReverse[0x7F & mem_offset];
- if (!ByteReverseBuilt)
- BuildByteReverse ();
+ /*
+ * NOTE: The max offset address is 128 or half the reversal table. So
+ * the LSB is always zero and counts as a built in shift of one bit.
+ * So even though we need to shift 3 bits to make room for the command,
+ * we only need to shift twice more because of the built in shift.
+ */
- mem_offset = ByteReverse[0x7F & mem_offset]; /* Reverse address */
- /*
- * NOTE: The max offset address is 128 or half the reversal table. So the
- * LSB is always zero and counts as a built in shift of one bit. So even
- * though we need to shift 3 bits to make room for the command, we only
- * need to shift twice more because of the built in shift.
- */
- mem_offset <<= 2; /* Shift for command */
- mem_offset |= EPROM_WRITE; /* Add command */
+ /* Shift for command */
+ mem_offset <<= 2;
+ /* Add command */
+ mem_offset |= EPROM_WRITE;
- eeprom_put_byte (addr, mem_offset, SIZE_ADDR_OP); /* Output chip address */
+ /* Output chip address */
+ eeprom_put_byte(addr, mem_offset, SIZE_ADDR_OP);
- data = ByteReverse[0xFF & data];/* Reverse data */
- eeprom_put_byte (addr, data, NUM_OF_BITS); /* Output chip data */
+ /* Reverse data */
+ data = ByteReverse[0xFF & data];
+ /* Output chip data */
+ eeprom_put_byte(addr, data, NUM_OF_BITS);
- pci_write_32 ((u_int32_t *) addr, 0); /* Remove Chip Select from
- * EEPROM */
+ /* Remove Chip Select from EEPROM */
+ pci_write_32((u_int32_t *) addr, 0);
/*
-** Must see Data In at a low state before completing this transaction.
-**
-** Afterwards, the data bit will return to a high state, ~6 ms, terminating
-** the operation.
-*/
- pci_write_32 ((u_int32_t *) addr, EPROM_ENCS); /* Re-enable Chip Select */
- temp = pci_read_32 ((u_int32_t *) addr); /* discard first read */
- temp = pci_read_32 ((u_int32_t *) addr);
- if (temp & EPROM_ACTIVE_IN_BIT)
- {
- temp = pci_read_32 ((u_int32_t *) addr);
- if (temp & EPROM_ACTIVE_IN_BIT)
- {
- pci_write_32 ((u_int32_t *) addr, 0); /* Remove Chip Select
- * from EEPROM */
- return (1);
- }
- }
- count = 1000;
- while (count--)
- {
- for (temp = 0; temp < 0x10; temp++)
- OS_uwait_dummy ();
-
- if (pci_read_32 ((u_int32_t *) addr) & EPROM_ACTIVE_IN_BIT)
- break;
- }
-
- if (count == -1)
- return (2);
-
- return (0);
+ * Must see Data In at a low state before completing this transaction.
+ *
+ * Afterwards, the data bit will return to a high state, ~6 ms, terminating
+ * the operation.
+ */
+ /* Re-enable Chip Select */
+ pci_write_32((u_int32_t *) addr, EPROM_ENCS);
+ /* discard first read */
+ temp = pci_read_32((u_int32_t *) addr);
+ temp = pci_read_32((u_int32_t *) addr);
+ if (temp & EPROM_ACTIVE_IN_BIT) {
+ temp = pci_read_32((u_int32_t *) addr);
+ if (temp & EPROM_ACTIVE_IN_BIT) {
+ /* Remove Chip Select from EEPROM */
+ pci_write_32((u_int32_t *) addr, 0);
+ return 1;
+ }
+ }
+ count = 1000;
+ while (count--) {
+ for (temp = 0; temp < 0x10; temp++)
+ OS_uwait_dummy();
+
+ if (pci_read_32((u_int32_t *) addr) & EPROM_ACTIVE_IN_BIT)
+ break;
+ }
+
+ if (count == -1)
+ return 2;
+
+ return 0;
}
-
/*------------------------------------------------------------------------
* pmcGetBuffValue - read the specified value from buffer
*------------------------------------------------------------------------
*/
-long
-pmcGetBuffValue (char *ptr, int size)
+static long pmcGetBuffValue(char *ptr, int size)
{
- long value = 0;
- int index;
+ long value = 0;
+ int index;
- for (index = 0; index < size; ++index)
- {
- value <<= 8;
- value |= ptr[index] & 0xFF;
- }
+ for (index = 0; index < size; ++index) {
+ value <<= 8;
+ value |= ptr[index] & 0xFF;
+ }
- return value;
+ return value;
}
-
/*------------------------------------------------------------------------
* pmcSetBuffValue - save the specified value to buffer
*------------------------------------------------------------------------
*/
-void
-pmcSetBuffValue (char *ptr, long value, int size)
+static void pmcSetBuffValue(char *ptr, long value, int size)
{
- int index = size;
+ int index = size;
- while (--index >= 0)
- {
- ptr[index] = (char) (value & 0xFF);
- value >>= 8;
- }
+ while (--index >= 0) {
+ ptr[index] = (char)(value & 0xFF);
+ value >>= 8;
+ }
}
-
/*------------------------------------------------------------------------
* pmc_eeprom_read_buffer - read EEPROM data into specified buffer
*------------------------------------------------------------------------
*/
void
-pmc_eeprom_read_buffer (long addr, long mem_offset, char *dest_ptr, int size)
+pmc_eeprom_read_buffer(long addr, long mem_offset, char *dest_ptr, int size)
{
- while (--size >= 0)
- *dest_ptr++ = (char) pmc_eeprom_read (addr, mem_offset++);
+ while (--size >= 0)
+ *dest_ptr++ = (char)pmc_eeprom_read(addr, mem_offset++);
}
-
/*------------------------------------------------------------------------
* pmc_eeprom_write_buffer - write EEPROM data from specified buffer
*------------------------------------------------------------------------
*/
void
-pmc_eeprom_write_buffer (long addr, long mem_offset, char *dest_ptr, int size)
+pmc_eeprom_write_buffer(long addr, long mem_offset, char *dest_ptr, int size)
{
- enable_pmc_eeprom (addr);
+ enable_pmc_eeprom(addr);
- while (--size >= 0)
- pmc_eeprom_write (addr, mem_offset++, *dest_ptr++);
+ while (--size >= 0)
+ pmc_eeprom_write(addr, mem_offset++, *dest_ptr++);
- disable_pmc_eeprom (addr);
+ disable_pmc_eeprom(addr);
}
-
/*------------------------------------------------------------------------
* pmcCalcCrc - calculate the CRC for the serial EEPROM structure
*------------------------------------------------------------------------
*/
-u_int32_t
-pmcCalcCrc_T01 (void *bufp)
+static u_int32_t pmcCalcCrc_T01(void *bufp)
{
- FLD_TYPE2 *buf = bufp;
- u_int32_t crc; /* CRC of the structure */
+ FLD_TYPE2 *buf = bufp;
+ /* CRC of the structure */
+ u_int32_t crc;
- /* Calc CRC for type and length fields */
- sbeCrc (
- (u_int8_t *) &buf->type,
- (u_int32_t) STRUCT_OFFSET (FLD_TYPE1, Crc32),
- (u_int32_t) 0,
- (u_int32_t *) &crc);
+ /* Calc CRC for type and length fields */
+ sbeCrc((u_int8_t *) &buf->type,
+ (u_int32_t) STRUCT_OFFSET(FLD_TYPE1, Crc32),
+ (u_int32_t) 0, (u_int32_t *) &crc);
#ifdef EEPROM_TYPE_DEBUG
- pr_info("sbeCrc: crc 1 calculated as %08x\n", crc); /* RLD DEBUG */
+ /* RLD DEBUG */
+ pr_info("sbeCrc: crc 1 calculated as %08x\n", crc);
#endif
- return ~crc;
+ return ~crc;
}
-u_int32_t
-pmcCalcCrc_T02 (void *bufp)
+static u_int32_t pmcCalcCrc_T02(void *bufp)
{
- FLD_TYPE2 *buf = bufp;
- u_int32_t crc; /* CRC of the structure */
-
- /* Calc CRC for type and length fields */
- sbeCrc (
- (u_int8_t *) &buf->type,
- (u_int32_t) STRUCT_OFFSET (FLD_TYPE2, Crc32),
- (u_int32_t) 0,
- (u_int32_t *) &crc);
-
- /* Calc CRC for remaining fields */
- sbeCrc (
- (u_int8_t *) &buf->Id[0],
- (u_int32_t) (sizeof (FLD_TYPE2) - STRUCT_OFFSET (FLD_TYPE2, Id)),
- (u_int32_t) crc,
- (u_int32_t *) &crc);
+ FLD_TYPE2 *buf = bufp;
+ /* CRC of the structure */
+ u_int32_t crc;
+
+ /* Calc CRC for type and length fields */
+ sbeCrc((u_int8_t *) &buf->type,
+ (u_int32_t) STRUCT_OFFSET(FLD_TYPE2, Crc32),
+ (u_int32_t) 0, (u_int32_t *) &crc);
+
+ /* Calc CRC for remaining fields */
+ sbeCrc((u_int8_t *) &buf->Id[0],
+ (u_int32_t) (sizeof(FLD_TYPE2) - STRUCT_OFFSET(FLD_TYPE2, Id)),
+ (u_int32_t) crc, (u_int32_t *) &crc);
#ifdef EEPROM_TYPE_DEBUG
- pr_info("sbeCrc: crc 2 calculated as %08x\n", crc); /* RLD DEBUG */
+ /* RLD DEBUG */
+ pr_info("sbeCrc: crc 2 calculated as %08x\n", crc);
#endif
- return crc;
+ return crc;
}
-
/*------------------------------------------------------------------------
* pmc_init_seeprom - initialize the serial EEPROM structure
*------------------------------------------------------------------------
* serial number field.
*/
-void
-pmc_init_seeprom (u_int32_t addr, u_int32_t serialNum)
+void pmc_init_seeprom(u_int32_t addr, u_int32_t serialNum)
{
- PROMFORMAT buffer; /* Memory image of structure */
- u_int32_t crc; /* CRC of structure */
- time_t createTime;
+ /* Memory image of structure */
+ PROMFORMAT buffer;
+ /* CRC of structure */
+ u_int32_t crc;
+ time_t createTime;
- createTime = get_seconds ();
+ createTime = get_seconds();
- /* use template data */
- memcpy(&buffer.fldType2, mfg_template, sizeof(buffer.fldType2));
+ /* use template data */
+ memcpy(&buffer.fldType2, mfg_template, sizeof(buffer.fldType2));
- /* Update serial number field in buffer */
- pmcSetBuffValue (&buffer.fldType2.Serial[3], serialNum, 3);
+ /* Update serial number field in buffer */
+ pmcSetBuffValue(&buffer.fldType2.Serial[3], serialNum, 3);
- /* Update create time field in buffer */
- pmcSetBuffValue (&buffer.fldType2.CreateTime[0], createTime, 4);
+ /* Update create time field in buffer */
+ pmcSetBuffValue(&buffer.fldType2.CreateTime[0], createTime, 4);
- /* Update CRC field in buffer */
- crc = pmcCalcCrc_T02 (&buffer);
- pmcSetBuffValue (&buffer.fldType2.Crc32[0], crc, 4);
+ /* Update CRC field in buffer */
+ crc = pmcCalcCrc_T02(&buffer);
+ pmcSetBuffValue(&buffer.fldType2.Crc32[0], crc, 4);
#ifdef DEBUG
- for (i = 0; i < sizeof (FLD_TYPE2); ++i)
- pr_info("[%02X] = %02X\n", i, buffer.bytes[i] & 0xFF);
+ for (i = 0; i < sizeof(FLD_TYPE2); ++i)
+ pr_info("[%02X] = %02X\n", i, buffer.bytes[i] & 0xFF);
#endif
- /* Write structure to serial EEPROM */
- pmc_eeprom_write_buffer (addr, EE_MFG, (char *) &buffer, sizeof (FLD_TYPE2));
+ /* Write structure to serial EEPROM */
+ pmc_eeprom_write_buffer(addr, EE_MFG, (char *)&buffer,
+ sizeof(FLD_TYPE2));
}
-
-char
-pmc_verify_cksum (void *bufp)
+char pmc_verify_cksum(void *bufp)
{
- FLD_TYPE1 *buf1 = bufp;
- FLD_TYPE2 *buf2 = bufp;
- u_int32_t crc1, crc2; /* CRC read from EEPROM */
+ FLD_TYPE1 *buf1 = bufp;
+ FLD_TYPE2 *buf2 = bufp;
+ /* CRC read from EEPROM */
+ u_int32_t crc1, crc2;
- /* Retrieve contents of CRC field */
- crc1 = pmcGetBuffValue (&buf1->Crc32[0], sizeof (buf1->Crc32));
+ /* Retrieve contents of CRC field */
+ crc1 = pmcGetBuffValue(&buf1->Crc32[0], sizeof(buf1->Crc32));
#ifdef EEPROM_TYPE_DEBUG
- pr_info("EEPROM: chksum 1 reads as %08x\n", crc1); /* RLD DEBUG */
+ /* RLD DEBUG */
+ pr_info("EEPROM: chksum 1 reads as %08x\n", crc1);
#endif
- if ((buf1->type == PROM_FORMAT_TYPE1) &&
- (pmcCalcCrc_T01 ((void *) buf1) == crc1))
- return PROM_FORMAT_TYPE1; /* checksum type 1 verified */
+ if ((buf1->type == PROM_FORMAT_TYPE1) &&
+ (pmcCalcCrc_T01((void *)buf1) == crc1))
+ return PROM_FORMAT_TYPE1; /* checksum type 1 verified */
- crc2 = pmcGetBuffValue (&buf2->Crc32[0], sizeof (buf2->Crc32));
+ crc2 = pmcGetBuffValue(&buf2->Crc32[0], sizeof(buf2->Crc32));
#ifdef EEPROM_TYPE_DEBUG
- pr_info("EEPROM: chksum 2 reads as %08x\n", crc2); /* RLD DEBUG */
+ /* RLD DEBUG */
+ pr_info("EEPROM: chksum 2 reads as %08x\n", crc2);
#endif
- if ((buf2->type == PROM_FORMAT_TYPE2) &&
- (pmcCalcCrc_T02 ((void *) buf2) == crc2))
- return PROM_FORMAT_TYPE2; /* checksum type 2 verified */
+ if ((buf2->type == PROM_FORMAT_TYPE2) &&
+ (pmcCalcCrc_T02((void *)buf2) == crc2))
+ return PROM_FORMAT_TYPE2; /* checksum type 2 verified */
- return PROM_FORMAT_Unk; /* failed to validate */
+ /* failed to validate */
+ return PROM_FORMAT_Unk;
}
-
-
-/*** End-of-File ***/
return NULL;
}
-
-ci_t *__init
-c4_new (void *hi)
-{
- ci_t *ci;
-
-#ifdef SBE_MAP_DEBUG
- pr_warning("c4_new() entered, ci needs %u.\n",
- (unsigned int) sizeof (ci_t));
-#endif
-
- ci = (ci_t *) OS_kmalloc (sizeof (ci_t));
- if (ci)
- {
- ci->hdw_info = hi;
- ci->state = C_INIT; /* mark as hardware not available */
- ci->next = c4_list;
- c4_list = ci;
- ci->brdno = ci->next ? ci->next->brdno + 1 : 0;
- } else
- pr_warning("failed CI malloc, size %u.\n",
- (unsigned int) sizeof (ci_t));
-
- if (!CI)
- CI = ci; /* DEBUG, only board 0 usage */
- return ci;
-}
-
-
/***
* Check port state and set LED states using watchdog or ioctl...
* also check for in-band SF loopback commands (& cause results if they are there)
for (j = 0; j < MUSYCC_NCHANS; j++)
{
if (pi->chan[j])
- OS_kfree (pi->chan[j]); /* free mch_t struct */
+ kfree(pi->chan[j]); /* free mch_t struct */
}
- OS_kfree (pi->regram_saved);
+ kfree(pi->regram_saved);
}
- OS_kfree (ci->iqd_p_saved);
- OS_kfree (ci);
+ kfree(ci->iqd_p_saved);
+ kfree(ci);
ci = next; /* cleanup next board, if any */
}
}
/* allocate channel structures for this port */
for (j = 0; j < MUSYCC_NCHANS; j++)
{
- ch = OS_kmalloc (sizeof (mch_t));
+ ch = kzalloc(sizeof(mch_t), GFP_KERNEL | GFP_DMA);
if (ch)
{
pi->chan[j] = ch;
ch->txd_num = txnum;
ch->rxix_irq_srv = 0;
- ch->mdr = OS_kmalloc (sizeof (struct mdesc) * rxnum);
- ch->mdt = OS_kmalloc (sizeof (struct mdesc) * txnum);
+ ch->mdr = kzalloc(sizeof(struct mdesc) * rxnum, GFP_KERNEL | GFP_DMA);
+ ch->mdt = kzalloc(sizeof(struct mdesc) * txnum, GFP_KERNEL | GFP_DMA);
if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
tmp = __constant_cpu_to_le32 (cxt1e1_max_mru | EOBIRQ_ENABLE);
else
i--;
OS_mem_token_free (ch->mdr[i].mem_token);
}
- OS_kfree (ch->mdt);
+ kfree(ch->mdt);
ch->mdt = NULL;
ch->txd_num = 0;
- OS_kfree (ch->mdr);
+ kfree(ch->mdr);
ch->mdr = NULL;
ch->rxd_num = 0;
ch->state = DOWN;
struct pci_dev *pdev[2];
unsigned long addr[2];
- unsigned long addr_mapped[2];
+ void __iomem *addr_mapped[2];
unsigned long len[2];
union
* system dependent callbacks
*/
-/**********/
-/* malloc */
-/**********/
-
-static inline void *
-OS_kmalloc (size_t size)
-{
- char *ptr = kmalloc (size, GFP_KERNEL | GFP_DMA);
-
- if (ptr)
- memset (ptr, 0, size);
- return ptr;
-}
-
-static inline void
-OS_kfree (void *x)
-{
- kfree (x);
-}
-
-
/****************/
/* memory token */
/****************/
OS_free_watchdog (struct watchdog *wd)
{
OS_stop_watchdog (wd);
- OS_kfree (wd);
+ kfree(wd);
return 0;
}
tbl = &CRCTable;
genCrcTable(tbl);
#else
- tbl = (u_int32_t *) OS_kmalloc(CRC_TABLE_ENTRIES * sizeof(u_int32_t));
+ tbl = kzalloc(CRC_TABLE_ENTRIES * sizeof(u_int32_t),
+ GFP_KERNEL);
if (!tbl) {
*result = 0; /* dummy up return value due to malloc
* failure */
#ifndef STATIC_CRC_TABLE
crcTableInit = 0;
- OS_kfree(tbl);
+ kfree(tbl);
#endif
}
char *spd;
struct sbe_brd_info *bip;
- bip = OS_kmalloc(sizeof(struct sbe_brd_info));
+ bip = kzalloc(sizeof(struct sbe_brd_info), GFP_KERNEL | GFP_DMA);
if (!bip)
return -ENOMEM;
* 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.
- *
- *
- * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
- *
- * This is shared code between Digi's CVS archive and the
- * Linux Kernel sources.
- * Changing the source just for reformatting needlessly breaks
- * our CVS diff history.
- *
- * Send any bug fixes/changes to: Eng.Linux at digi dot com.
- * Thank you.
- *
*/
/*
#include "dgap.h"
-#define init_MUTEX(sem) sema_init(sem, 1)
-#define DECLARE_MUTEX(name) \
- struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)
-
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Digi International, http://www.digi.com");
MODULE_DESCRIPTION("Driver for the Digi International EPCA PCI based product line");
MODULE_SUPPORTED_DEVICE("dgap");
-/**************************************************************************
- *
- * protos for this file
- *
- */
-
static int dgap_start(void);
static void dgap_init_globals(void);
static int dgap_found_board(struct pci_dev *pdev, int id);
static int dgap_do_remap(struct board_t *brd);
static irqreturn_t dgap_intr(int irq, void *voidbrd);
-/* Our function prototypes */
static int dgap_tty_open(struct tty_struct *tty, struct file *file);
static void dgap_tty_close(struct tty_struct *tty, struct file *file);
static int dgap_block_til_ready(struct tty_struct *tty, struct file *file,
static int dgap_event(struct board_t *bd);
static void dgap_poll_tasklet(unsigned long data);
-static void dgap_cmdb(struct channel_t *ch, uchar cmd, uchar byte1,
- uchar byte2, uint ncmds);
-static void dgap_cmdw(struct channel_t *ch, uchar cmd, u16 word, uint ncmds);
+static void dgap_cmdb(struct channel_t *ch, u8 cmd, u8 byte1,
+ u8 byte2, uint ncmds);
+static void dgap_cmdw(struct channel_t *ch, u8 cmd, u16 word, uint ncmds);
static void dgap_wmove(struct channel_t *ch, char *buf, uint cnt);
static int dgap_param(struct tty_struct *tty);
static void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf,
static uint dgap_config_get_altpin(struct board_t *bd);
static int dgap_ms_sleep(ulong ms);
-static void dgap_do_bios_load(struct board_t *brd, const uchar *ubios, int len);
-static void dgap_do_fep_load(struct board_t *brd, const uchar *ufep, int len);
+static void dgap_do_bios_load(struct board_t *brd, const u8 *ubios, int len);
+static void dgap_do_fep_load(struct board_t *brd, const u8 *ufep, int len);
#ifdef DIGI_CONCENTRATORS_SUPPORTED
-static void dgap_do_conc_load(struct board_t *brd, uchar *uaddr, int len);
+static void dgap_do_conc_load(struct board_t *brd, u8 *uaddr, int len);
#endif
static int dgap_after_config_loaded(int board);
static int dgap_finalize_board_init(struct board_t *brd);
static void dgap_get_vpd(struct board_t *brd);
static void dgap_do_reset_board(struct board_t *brd);
-static int dgap_do_wait_for_bios(struct board_t *brd);
-static int dgap_do_wait_for_fep(struct board_t *brd);
+static int dgap_test_bios(struct board_t *brd);
+static int dgap_test_fep(struct board_t *brd);
static int dgap_tty_register_ports(struct board_t *brd);
static int dgap_firmware_load(struct pci_dev *pdev, int card_type);
-/* Driver unload function */
static void dgap_cleanup_module(void);
module_exit(dgap_cleanup_module);
.owner = THIS_MODULE,
};
-/*
- * Globals
- */
static uint dgap_NumBoards;
static struct board_t *dgap_Board[MAXBOARDS];
static ulong dgap_poll_counter;
static char *dgap_config_buf;
static int dgap_driver_state = DRIVER_INITIALIZED;
-DEFINE_SPINLOCK(dgap_dl_lock);
static wait_queue_head_t dgap_dl_wait;
-static int dgap_dl_action;
static int dgap_poll_tick = 20; /* Poll interval - 20 ms */
-/*
- * Static vars.
- */
static struct class *dgap_class;
static struct board_t *dgap_BoardsByMajor[256];
*/
struct board_id {
uint config_type;
- uchar *name;
+ u8 *name;
uint maxports;
uint dpatype;
};
};
struct firmware_info {
- uchar *conf_name; /* dgap.conf */
- uchar *bios_name; /* BIOS filename */
- uchar *fep_name; /* FEP filename */
- uchar *con_name; /* Concentrator filename FIXME*/
+ u8 *conf_name; /* dgap.conf */
+ u8 *bios_name; /* BIOS filename */
+ u8 *fep_name; /* FEP filename */
+ u8 *con_name; /* Concentrator filename FIXME*/
int num; /* sequence number */
};
class_destroy(dgap_class);
unregister_chrdev(DIGI_DGAP_MAJOR, "dgap");
- kfree(dgap_config_buf);
-
for (i = 0; i < dgap_NumBoards; ++i) {
dgap_remove_ports_sysfiles(dgap_Board[i]);
dgap_tty_uninit(dgap_Board[i]);
if (i)
brd->state = BOARD_FAILED;
- pr_info("dgap: board %d: %s (rev %d), irq %ld, %s\n",
- dgap_NumBoards, brd->name, brd->rev, brd->irq,
- brd->state ? "NOT READY\0" : "READY\0");
+ pr_info("dgap: board %d: %s (rev %d), irq %ld\n",
+ dgap_NumBoards, brd->name, brd->rev, brd->irq);
return 0;
}
dgap_get_vpd(brd);
dgap_do_reset_board(brd);
- if (fw_info[card_type].conf_name) {
+ if ((fw_info[card_type].conf_name) && !dgap_config_buf) {
ret = request_firmware(&fw, fw_info[card_type].conf_name,
&pdev->dev);
if (ret) {
fw_info[card_type].conf_name);
return ret;
}
+
+ dgap_config_buf = kmalloc(fw->size + 1, GFP_KERNEL);
if (!dgap_config_buf) {
- dgap_config_buf = kmalloc(fw->size + 1, GFP_ATOMIC);
- if (!dgap_config_buf) {
- release_firmware(fw);
- return -ENOMEM;
- }
+ release_firmware(fw);
+ return -ENOMEM;
}
memcpy(dgap_config_buf, fw->data, fw->size);
release_firmware(fw);
dgap_config_buf[fw->size + 1] = '\0';
- if (dgap_parsefile(&dgap_config_buf, TRUE) != 0)
+ if (dgap_parsefile(&dgap_config_buf, TRUE) != 0) {
+ kfree(dgap_config_buf);
return -EINVAL;
+ }
+ kfree(dgap_config_buf);
}
ret = dgap_after_config_loaded(brd->boardnum);
release_firmware(fw);
/* Wait for BIOS to test board... */
- if (!dgap_do_wait_for_bios(brd))
- return -ENXIO;
+ ret = dgap_test_bios(brd);
+ if (ret)
+ return ret;
}
if (fw_info[card_type].fep_name) {
release_firmware(fw);
/* Wait for FEP to load on board... */
- if (!dgap_do_wait_for_fep(brd))
- return -ENXIO;
+ ret = dgap_test_fep(brd);
+ if (ret)
+ return ret;
}
#ifdef DIGI_CONCENTRATORS_SUPPORTED
init_timer(&dgap_poll_timer);
init_waitqueue_head(&dgap_dl_wait);
- dgap_dl_action = 0;
}
/************************************************************************
int i;
int tlw;
uint true_count = 0;
- uchar *vaddr;
- uchar modem = 0;
+ u8 *vaddr;
+ u8 modem = 0;
struct channel_t *ch;
struct bs_t *bs;
struct cm_t *cm;
* dgap_sniff - Dump data out to the "sniff" buffer if the
* proc sniff file is opened...
*/
-static void dgap_sniff_nowait_nolock(struct channel_t *ch, uchar *text,
- uchar *buf, int len)
+static void dgap_sniff_nowait_nolock(struct channel_t *ch, u8 *text,
+ u8 *buf, int len)
{
struct timeval tv;
int n;
int flip_len;
int len = 0;
int n = 0;
- uchar *buf;
- uchar tmpchar;
+ u8 *buf;
+ u8 tmpchar;
int s = 0;
if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
struct channel_t *ch = NULL;
struct un_t *un = NULL;
struct bs_t *bs = NULL;
- uchar tbusy;
+ u8 tbusy;
uint chars = 0;
u16 thead, ttail, tmask, chead, ctail;
ulong lock_flags = 0;
n -= remain;
vaddr = ch->ch_taddr + head;
- memcpy_toio(vaddr, (uchar *) buf, remain);
- dgap_sniff_nowait_nolock(ch, "USER WRITE", (uchar *) buf,
+ memcpy_toio(vaddr, (u8 *) buf, remain);
+ dgap_sniff_nowait_nolock(ch, "USER WRITE", (u8 *) buf,
remain);
head = ch->ch_tstart;
vaddr = ch->ch_taddr + head;
remain = n;
- memcpy_toio(vaddr, (uchar *) buf, remain);
- dgap_sniff_nowait_nolock(ch, "USER WRITE", (uchar *)buf,
+ memcpy_toio(vaddr, (u8 *) buf, remain);
+ dgap_sniff_nowait_nolock(ch, "USER WRITE", (u8 *)buf,
remain);
head += remain;
struct channel_t *ch;
struct un_t *un;
int result = -EIO;
- uchar mstat = 0;
+ u8 mstat = 0;
ulong lock_flags;
if (!tty || tty->magic != TTY_MAGIC)
static int dgap_get_modem_info(struct channel_t *ch, unsigned int __user *value)
{
int result = 0;
- uchar mstat = 0;
+ u8 mstat = 0;
ulong lock_flags;
int rc = 0;
* Copies the BIOS code from the user to the board,
* and starts the BIOS running.
*/
-static void dgap_do_bios_load(struct board_t *brd, const uchar *ubios, int len)
+static void dgap_do_bios_load(struct board_t *brd, const u8 *ubios, int len)
{
- uchar *addr;
+ u8 *addr;
uint offset;
int i;
/*
* Checks to see if the BIOS completed running on the card.
*/
-static int dgap_do_wait_for_bios(struct board_t *brd)
+static int dgap_test_bios(struct board_t *brd)
{
- uchar *addr;
+ u8 *addr;
u16 word;
u16 err1;
u16 err2;
- int ret = 0;
if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
- return ret;
+ return -EINVAL;
addr = brd->re_map_membase;
word = readw(addr + POSTAREA);
while (brd->wait_for_bios < 1000) {
/* Check to see if BIOS thinks board is good. (GD). */
if (word == *(u16 *) "GD")
- return 1;
+ return 0;
msleep_interruptible(10);
brd->wait_for_bios++;
word = readw(addr + POSTAREA);
brd->state = BOARD_FAILED;
brd->dpastatus = BD_NOBIOS;
- return ret;
+ return -EIO;
}
/*
* Copies the FEP code from the user to the board,
* and starts the FEP running.
*/
-static void dgap_do_fep_load(struct board_t *brd, const uchar *ufep, int len)
+static void dgap_do_fep_load(struct board_t *brd, const u8 *ufep, int len)
{
- uchar *addr;
+ u8 *addr;
uint offset;
if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
* it its config string describing how the concentrators look.
*/
if ((brd->type == PCX) || (brd->type == PEPC)) {
- uchar string[100];
- uchar *config, *xconfig;
+ u8 string[100];
+ u8 *config, *xconfig;
int i = 0;
xconfig = dgap_create_config_string(brd, string);
/*
* Waits for the FEP to report thats its ready for us to use.
*/
-static int dgap_do_wait_for_fep(struct board_t *brd)
+static int dgap_test_fep(struct board_t *brd)
{
- uchar *addr;
+ u8 *addr;
u16 word;
u16 err1;
u16 err2;
- int ret = 0;
if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
- return ret;
+ return -EINVAL;
addr = brd->re_map_membase;
word = readw(addr + FEPSTAT);
if (word == *(u16 *) "5A")
brd->bd_flags |= BD_FEP5PLUS;
- return 1;
+ return 0;
}
msleep_interruptible(10);
brd->wait_for_fep++;
brd->state = BOARD_FAILED;
brd->dpastatus = BD_NOFEP;
- return ret;
+ return -EIO;
}
/*
*/
static void dgap_do_reset_board(struct board_t *brd)
{
- uchar check;
+ u8 check;
u32 check1;
u32 check2;
int i = 0;
/*
* Sends a concentrator image into the FEP5 board.
*/
-static void dgap_do_conc_load(struct board_t *brd, uchar *uaddr, int len)
+static void dgap_do_conc_load(struct board_t *brd, u8 *uaddr, int len)
{
char *vaddr;
u16 offset = 0;
u16 vpd_offset;
u16 image_length;
u16 i;
- uchar byte1;
- uchar byte2;
+ u8 byte1;
+ u8 byte2;
/*
* Poke the magic number at the PCI Rom Address location.
* in the cmd buffer before returning.
*
*=======================================================================*/
-static void dgap_cmdb(struct channel_t *ch, uchar cmd, uchar byte1,
- uchar byte2, uint ncmds)
+static void dgap_cmdb(struct channel_t *ch, u8 cmd, u8 byte1,
+ u8 byte2, uint ncmds)
{
char *vaddr = NULL;
struct cm_t *cm_addr = NULL;
* Put the data in the circular command buffer.
*/
writeb(cmd, (char *) (vaddr + head + CMDSTART + 0));
- writeb((uchar) ch->ch_portnum, (char *) (vaddr + head + CMDSTART + 1));
+ writeb((u8) ch->ch_portnum, (char *) (vaddr + head + CMDSTART + 1));
writeb(byte1, (char *) (vaddr + head + CMDSTART + 2));
writeb(byte2, (char *) (vaddr + head + CMDSTART + 3));
* in the cmd buffer before returning.
*
*=======================================================================*/
-static void dgap_cmdw(struct channel_t *ch, uchar cmd, u16 word, uint ncmds)
+static void dgap_cmdw(struct channel_t *ch, u8 cmd, u16 word, uint ncmds)
{
char *vaddr = NULL;
struct cm_t *cm_addr = NULL;
* Put the data in the circular command buffer.
*/
writeb(cmd, (char *) (vaddr + head + CMDSTART + 0));
- writeb((uchar) ch->ch_portnum, (char *) (vaddr + head + CMDSTART + 1));
+ writeb((u8) ch->ch_portnum, (char *) (vaddr + head + CMDSTART + 1));
writew((u16) word, (char *) (vaddr + head + CMDSTART + 2));
head = (head + 4) & (CMDMAX - CMDSTART - 4);
*/
/* Write an FF to tell the FEP that we want an extended command */
- writeb((uchar) 0xff, (char *) (vaddr + head + CMDSTART + 0));
+ writeb((u8) 0xff, (char *) (vaddr + head + CMDSTART + 0));
- writeb((uchar) ch->ch_portnum, (uchar *) (vaddr + head + CMDSTART + 1));
+ writeb((u8) ch->ch_portnum, (u8 *) (vaddr + head + CMDSTART + 1));
writew((u16) cmd, (char *) (vaddr + head + CMDSTART + 2));
/*
*/
static uint dgap_get_custom_baud(struct channel_t *ch)
{
- uchar *vaddr;
+ u8 *vaddr;
ulong offset = 0;
uint value = 0;
u16 head;
u16 cflag;
u16 iflag;
- uchar mval;
- uchar hflow;
+ u8 mval;
+ u8 hflow;
if (!tty || tty->magic != TTY_MAGIC)
return -ENXIO;
ch->ch_hflow = hflow;
/* Okay to have channel and board locks held calling this */
- dgap_cmdb(ch, SHFLOW, (uchar) hflow, 0xff, 0);
+ dgap_cmdb(ch, SHFLOW, (u8) hflow, 0xff, 0);
}
ch->ch_mostat = mval;
/* Okay to have channel and board locks held calling this */
- dgap_cmdb(ch, SMODEM, (uchar) mval, D_RTS(ch)|D_DTR(ch), 0);
+ dgap_cmdb(ch, SMODEM, (u8) mval, D_RTS(ch)|D_DTR(ch), 0);
}
/*
ulong lock_flags;
ulong lock_flags2;
struct bs_t *bs;
- uchar *event;
- uchar *vaddr = NULL;
+ u8 *event;
+ u8 *vaddr = NULL;
struct ev_t *eaddr = NULL;
uint head;
uint tail;
# define FALSE 0
#endif
-/* Required for our shared headers! */
-typedef unsigned char uchar;
-
#if !defined(TTY_FLIPBUF_SIZE)
# define TTY_FLIPBUF_SIZE 512
#endif
/*
* defines from dgap_pci.h
- */
+ */
#define PCIMAX 32 /* maximum number of PCI boards */
#define DIGI_VID 0x114F
ECHOCTL | ECHOKE | IEXTEN)
#ifndef _POSIX_VDISABLE
-#define _POSIX_VDISABLE '\0'
+#define _POSIX_VDISABLE ('\0')
#endif
#define SNIFF_MAX 65536 /* Sniff buffer size (2^n) */
#define EVSTART 0x0800L /* Start of event buffer */
#define EVMAX 0x0c00L /* End of event buffer */
#define FEP5_PLUS 0x0E40 /* ASCII '5' and ASCII 'A' is here */
-#define ECS_SEG 0x0E44 /* Segment of the extended channel structure */
-#define LINE_SPEED 0x10 /* Offset into ECS_SEG for line speed */
- /* if the fep has extended capabilities */
+#define ECS_SEG 0x0E44 /* Segment of the extended */
+ /* channel structure */
+#define LINE_SPEED 0x10 /* Offset into ECS_SEG for line */
+ /* speed if the fep has extended */
+ /* capabilities */
/* BIOS MAGIC SPOTS */
#define ERROR 0x0C14L /* BIOS error code */
#define FEPTIMEOUT 200000
-#define ENABLE_INTR 0x0e04 /* Enable interrupts flag */
-#define FEPPOLL_MIN 1 /* minimum of 1 millisecond */
-#define FEPPOLL_MAX 20 /* maximum of 20 milliseconds */
-#define FEPPOLL 0x0c26 /* Fep event poll interval */
+#define ENABLE_INTR 0x0e04 /* Enable interrupts flag */
+#define FEPPOLL_MIN 1 /* minimum of 1 millisecond */
+#define FEPPOLL_MAX 20 /* maximum of 20 milliseconds */
+#define FEPPOLL 0x0c26 /* Fep event poll interval */
-#define IALTPIN 0x0080 /* Input flag to swap DSR <-> DCD */
+#define IALTPIN 0x0080 /* Input flag to swap DSR <-> DCD */
/************************************************************************
* FEP supported functions
#define SPINTFC 0xfc /* Reserved */
#define SCOMMODE 0xfd /* Set RS232/422 mode */
-
/************************************************************************
* Modes for SCOMMODE
************************************************************************/
#define MODE_232 0x00
#define MODE_422 0x01
-
/************************************************************************
* Event flags.
************************************************************************/
#define MC8E8K 36
#define AVANFS 42 /* start of Avanstar family definitions */
-#define A8P 42
+#define A8P 42
#define A16P 43
#define AVANFE 43 /* end of Avanstar family definitions */
-#define DA2000FS 44 /* start of AccelePort 2000 family definitions */
-#define DA22 44 /* AccelePort 2002 */
-#define DA24 45 /* AccelePort 2004 */
+#define DA2000FS 44 /* start of AccelePort 2000 family definitions */
+#define DA22 44 /* AccelePort 2002 */
+#define DA24 45 /* AccelePort 2004 */
#define DA28 46 /* AccelePort 2008 */
#define DA216 47 /* AccelePort 2016 */
#define DAR4 48 /* AccelePort RAS 4 port */
REQUESTED_CONCENTRATOR
};
-
-
/*
* Modem line constants are defined as macros because DSR and
* DCD are swapable using the ditty altpin option.
#define D_RI(ch) DM_RI /* Ring indicator */
#define D_DTR(ch) DM_DTR /* Data terminal ready */
-
/*************************************************************************
*
* Structures and closely related defines.
*
*************************************************************************/
-
/*
* A structure to hold a statistics counter. We also
* compute moving averages for this counter.
ulong ema; /* Exponential moving average */
};
-
/************************************************************************
* Device flag definitions for bd_flags.
************************************************************************/
u16 device; /* PCI device ID */
u16 subvendor; /* PCI subsystem vendor ID */
u16 subdevice; /* PCI subsystem device ID */
- uchar rev; /* PCI revision ID */
+ u8 rev; /* PCI revision ID */
uint pci_bus; /* PCI bus value */
uint pci_slot; /* PCI slot value */
u16 maxports; /* MAX ports this board can handle */
- uchar vpd[VPDSIZE]; /* VPD of board, if found */
+ u8 vpd[VPDSIZE]; /* VPD of board, if found */
u32 bd_flags; /* Board flags */
spinlock_t bd_lock; /* Used to protect board */
ulong irq; /* Interrupt request number */
ulong intr_count; /* Count of interrupts */
u32 intr_used; /* Non-zero if using interrupts */
- u32 intr_running; /* Non-zero if FEP knows its doing interrupts */
+ u32 intr_running; /* Non-zero if FEP knows its doing */
+ /* interrupts */
ulong port; /* Start of base io port of the card */
ulong port_end; /* End of base io port of the card */
ulong membase; /* Start of base memory of the card */
ulong membase_end; /* End of base memory of the card */
- uchar *re_map_port; /* Remapped io port of the card */
- uchar *re_map_membase;/* Remapped memory of the card */
+ u8 *re_map_port; /* Remapped io port of the card */
+ u8 *re_map_membase;/* Remapped memory of the card */
- uchar runwait; /* # Processes waiting for FEP */
- uchar inhibit_poller; /* Tells the poller to leave us alone */
+ u8 runwait; /* # Processes waiting for FEP */
+ u8 inhibit_poller; /* Tells the poller to leave us alone */
- struct channel_t *channels[MAXPORTS]; /* array of pointers to our channels. */
+ struct channel_t *channels[MAXPORTS]; /* array of pointers to our */
+ /* channels. */
struct tty_driver *SerialDriver;
struct tty_port *SerialPorts;
u32 dgap_Serial_Major;
u32 dgap_TransparentPrint_Major;
- struct bs_t *bd_bs; /* Base structure pointer */
+ struct bs_t *bd_bs; /* Base structure pointer */
- char *flipbuf; /* Our flip buffer, alloced if board is found */
- char *flipflagbuf; /* Our flip flag buffer, alloced if board is found */
+ char *flipbuf; /* Our flip buffer, alloced if */
+ /* board is found */
+ char *flipflagbuf; /* Our flip flag buffer, alloced */
+ /* if board is found */
- u16 dpatype; /* The board "type", as defined by DPA */
- u16 dpastatus; /* The board "status", as defined by DPA */
- wait_queue_head_t kme_wait; /* Needed for DPA support */
+ u16 dpatype; /* The board "type", as defined */
+ /* by DPA */
+ u16 dpastatus; /* The board "status", as defined */
+ /* by DPA */
+ wait_queue_head_t kme_wait; /* Needed for DPA support */
- u32 conc_dl_status; /* Status of any pending conc download */
+ u32 conc_dl_status; /* Status of any pending conc */
+ /* download */
};
-
-
/************************************************************************
* Unit flag definitions for un_flags.
************************************************************************/
struct device *un_sysfs;
};
-
/************************************************************************
* Device flag definitions for ch_flags.
************************************************************************/
#define SNIFF_WAIT_DATA 0x2
#define SNIFF_WAIT_SPACE 0x4
-
/************************************************************************
*** Definitions for Digi ditty(1) command.
************************************************************************/
#if !defined(TIOCMODG)
-#define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */
-#define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */
+#define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */
+#define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */
#ifndef TIOCM_LE
#define TIOCM_LE 0x01 /* line enable */
#endif
#if !defined(TIOCMSET)
-#define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */
-#define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */
+#define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */
+#define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */
#endif
#if !defined(TIOCMBIC)
-#define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */
-#define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */
+#define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */
+#define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */
#endif
-
#if !defined(TIOCSDTR)
#define TIOCSDTR (('e'<<8) | 0) /* set DTR */
#define TIOCCDTR (('e'<<8) | 1) /* clear DTR */
/* Adapter Memory */
#define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */
- /* control characters */
-#define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */
+ /* control characters */
+#define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */
/* control characters */
-#define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */
- /* flow control chars */
-#define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */
+#define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */
+ /* flow control chars */
+#define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */
/* flow control chars */
-#define DIGI_GEDELAY (('d'<<8) | 246) /* Get edelay */
-#define DIGI_SEDELAY (('d'<<8) | 247) /* Set edelay */
+#define DIGI_GEDELAY (('d'<<8) | 246) /* Get edelay */
+#define DIGI_SEDELAY (('d'<<8) | 247) /* Set edelay */
struct digiflow_t {
- unsigned char startc; /* flow cntl start char */
- unsigned char stopc; /* flow cntl stop char */
+ unsigned char startc; /* flow cntl start char */
+ unsigned char stopc; /* flow cntl stop char */
};
-
#ifdef FLOW_2200
-#define F2200_GETA (('e'<<8) | 104) /* Get 2x36 flow cntl flags */
-#define F2200_SETAW (('e'<<8) | 105) /* Set 2x36 flow cntl flags */
+#define F2200_GETA (('e'<<8) | 104) /* Get 2x36 flow cntl flags */
+#define F2200_SETAW (('e'<<8) | 105) /* Set 2x36 flow cntl flags */
#define F2200_MASK 0x03 /* 2200 flow cntl bit mask */
#define FCNTL_2200 0x01 /* 2x36 terminal flow cntl */
#define PCNTL_2200 0x02 /* 2x36 printer flow cntl */
unsigned char rw_data[128]; /* Data to read/write */
};
-/***********************************************************************
- * Shrink Buffer and Board Information definitions and structures.
-
- ************************************************************************/
- /* Board type return codes */
-#define PCXI_TYPE 1 /* Board type at the designated port is a PC/Xi */
-#define PCXM_TYPE 2 /* Board type at the designated port is a PC/Xm */
-#define PCXE_TYPE 3 /* Board type at the designated port is a PC/Xe */
-#define MCXI_TYPE 4 /* Board type at the designated port is a MC/Xi */
-#define COMXI_TYPE 5 /* Board type at the designated port is a COM/Xi */
-
- /* Non-Zero Result codes. */
-#define RESULT_NOBDFND 1 /* A Digi product at that port is not config installed */
-#define RESULT_NODESCT 2 /* A memory descriptor was not obtainable */
-#define RESULT_NOOSSIG 3 /* FEP/OS signature was not detected on the board */
-#define RESULT_TOOSML 4 /* Too small an area to shrink. */
-#define RESULT_NOCHAN 5 /* Channel structure for the board was not found */
-
-struct shrink_buf_struct {
- unsigned long shrink_buf_vaddr; /* Virtual address of board */
- unsigned long shrink_buf_phys; /* Physical address of board */
- unsigned long shrink_buf_bseg; /* Amount of board memory */
- unsigned long shrink_buf_hseg; /* '186 Beginning of Dual-Port */
-
- unsigned long shrink_buf_lseg; /* '186 Beginning of freed memory */
- unsigned long shrink_buf_mseg; /* Linear address from start of
- dual-port were freed memory
- begins, host viewpoint. */
-
- unsigned long shrink_buf_bdparam; /* Parameter for xxmemon and
- xxmemoff */
-
- unsigned long shrink_buf_reserva; /* Reserved */
- unsigned long shrink_buf_reservb; /* Reserved */
- unsigned long shrink_buf_reservc; /* Reserved */
- unsigned long shrink_buf_reservd; /* Reserved */
-
- unsigned char shrink_buf_result; /* Reason for call failing
- Zero is Good return */
- unsigned char shrink_buf_init; /* Non-Zero if it caused an
- xxinit call. */
-
- unsigned char shrink_buf_anports; /* Number of async ports */
- unsigned char shrink_buf_snports; /* Number of sync ports */
- unsigned char shrink_buf_type; /* Board type 1 = PC/Xi,
- 2 = PC/Xm,
- 3 = PC/Xe
- 4 = MC/Xi
- 5 = COMX/i */
- unsigned char shrink_buf_card; /* Card number */
-
-};
-
/************************************************************************
* Structure to get driver status information
************************************************************************/
char dinfo_version[16]; /* driver version */
};
-#define DIGI_GETDD (('d'<<8) | 248) /* get driver info */
+#define DIGI_GETDD (('d'<<8) | 248) /* get driver info */
/************************************************************************
* Structure used with ioctl commands for per-board information
char info_reserved[7]; /* for future expansion */
};
-#define DIGI_GETBD (('d'<<8) | 249) /* get board info */
+#define DIGI_GETBD (('d'<<8) | 249) /* get board info */
struct digi_stat {
unsigned int info_chan; /* Channel number (0 based) */
unsigned long info_reserved[8]; /* for future expansion */
};
-#define DIGI_GETSTAT (('d'<<8) | 244) /* get board info */
+#define DIGI_GETSTAT (('d'<<8) | 244) /* get board info */
/************************************************************************
*
* Structure used with ioctl commands for per-channel information
struct digi_ch {
unsigned long info_bdnum; /* Board number (0 based) */
unsigned long info_channel; /* Channel index number */
- unsigned long info_ch_cflag; /* Channel cflag */
- unsigned long info_ch_iflag; /* Channel iflag */
- unsigned long info_ch_oflag; /* Channel oflag */
+ unsigned long info_ch_cflag; /* Channel cflag */
+ unsigned long info_ch_iflag; /* Channel iflag */
+ unsigned long info_ch_oflag; /* Channel oflag */
unsigned long info_chsize; /* Channel structure size */
unsigned long info_sleep_stat; /* sleep status */
dev_t info_dev; /* device number */
#define INFO_CH_WLOW 0x0020
#define INFO_XXBUF_BUSY 0x0040
-#define DIGI_GETCH (('d'<<8) | 245) /* get board info */
+#define DIGI_GETCH (('d'<<8) | 245) /* get board info */
/* Board type definitions */
#define BD_TRIBOOT 0x8
#define BD_BADKME 0x80
-#define DIGI_LOOPBACK (('d'<<8) | 252) /* Enable/disable UART internal loopback */
-#define DIGI_SPOLL (('d'<<8) | 254) /* change poller rate */
+#define DIGI_LOOPBACK (('d'<<8) | 252) /* Enable/disable UART */
+ /* internal loopback */
+#define DIGI_SPOLL (('d'<<8) | 254) /* change poller rate */
-#define DIGI_SETCUSTOMBAUD _IOW('e', 106, int) /* Set integer baud rate */
-#define DIGI_GETCUSTOMBAUD _IOR('e', 107, int) /* Get integer baud rate */
-#define DIGI_RESET_PORT (('e'<<8) | 93) /* Reset port */
+#define DIGI_SETCUSTOMBAUD _IOW('e', 106, int) /* Set integer baud rate */
+#define DIGI_GETCUSTOMBAUD _IOR('e', 107, int) /* Get integer baud rate */
+#define DIGI_RESET_PORT (('e'<<8) | 93) /* Reset port */
/************************************************************************
* Channel information structure.
wait_queue_head_t ch_flags_wait;
u32 pscan_state;
- uchar pscan_savechar;
+ u8 pscan_savechar;
u32 ch_portnum; /* Port number, 0 offset. */
u32 ch_open_count; /* open count */
u32 ch_flags; /* Channel flags */
-
- u32 ch_close_delay; /* How long we should drop RTS/DTR for */
+ u32 ch_close_delay; /* How long we should drop */
+ /* RTS/DTR for */
u32 ch_cpstime; /* Time for CPS calculations */
tcflag_t ch_c_oflag; /* channel oflags */
tcflag_t ch_c_lflag; /* channel lflags */
- u16 ch_fepiflag; /* FEP tty iflags */
+ u16 ch_fepiflag; /* FEP tty iflags */
u16 ch_fepcflag; /* FEP tty cflags */
u16 ch_fepoflag; /* FEP tty oflags */
u16 ch_wopen; /* Waiting for open process cnt */
u16 ch_cook; /* Output character mask */
- uchar ch_card; /* Card channel is on */
- uchar ch_stopc; /* Stop character */
- uchar ch_startc; /* Start character */
-
- uchar ch_mostat; /* FEP output modem status */
- uchar ch_mistat; /* FEP input modem status */
- uchar ch_mforce; /* Modem values to be forced */
- uchar ch_mval; /* Force values */
- uchar ch_fepstopc; /* FEP stop character */
- uchar ch_fepstartc; /* FEP start character */
-
- uchar ch_astopc; /* Auxiliary Stop character */
- uchar ch_astartc; /* Auxiliary Start character */
- uchar ch_fepastopc; /* Auxiliary FEP stop char */
- uchar ch_fepastartc; /* Auxiliary FEP start char */
-
- uchar ch_hflow; /* FEP hardware handshake */
- uchar ch_dsr; /* stores real dsr value */
- uchar ch_cd; /* stores real cd value */
- uchar ch_tx_win; /* channel tx buffer window */
- uchar ch_rx_win; /* channel rx buffer window */
+ u8 ch_card; /* Card channel is on */
+ u8 ch_stopc; /* Stop character */
+ u8 ch_startc; /* Start character */
+
+ u8 ch_mostat; /* FEP output modem status */
+ u8 ch_mistat; /* FEP input modem status */
+ u8 ch_mforce; /* Modem values to be forced */
+ u8 ch_mval; /* Force values */
+ u8 ch_fepstopc; /* FEP stop character */
+ u8 ch_fepstartc; /* FEP start character */
+
+ u8 ch_astopc; /* Auxiliary Stop character */
+ u8 ch_astartc; /* Auxiliary Start character */
+ u8 ch_fepastopc; /* Auxiliary FEP stop char */
+ u8 ch_fepastartc; /* Auxiliary FEP start char */
+
+ u8 ch_hflow; /* FEP hardware handshake */
+ u8 ch_dsr; /* stores real dsr value */
+ u8 ch_cd; /* stores real cd value */
+ u8 ch_tx_win; /* channel tx buffer window */
+ u8 ch_rx_win; /* channel rx buffer window */
uint ch_custom_speed; /* Custom baud, if set */
- uint ch_baud_info; /* Current baud info for /proc output */
- ulong ch_rxcount; /* total of data received so far */
- ulong ch_txcount; /* total of data transmitted so far */
- ulong ch_err_parity; /* Count of parity errors on channel */
- ulong ch_err_frame; /* Count of framing errors on channel */
+ uint ch_baud_info; /* Current baud info for /proc output */
+ ulong ch_rxcount; /* total of data received so far */
+ ulong ch_txcount; /* total of data transmitted so far */
+ ulong ch_err_parity; /* Count of parity errors on channel */
+ ulong ch_err_frame; /* Count of framing errors on channel */
ulong ch_err_break; /* Count of breaks on channel */
ulong ch_err_overrun; /* Count of overruns on channel */
* Command structure definition.
************************************************************************/
struct cm_t {
- volatile unsigned short cm_head; /* Command buffer head offset */
- volatile unsigned short cm_tail; /* Command buffer tail offset */
- volatile unsigned short cm_start; /* start offset of buffer */
- volatile unsigned short cm_max; /* last offset of buffer */
+ unsigned short cm_head; /* Command buffer head offset */
+ unsigned short cm_tail; /* Command buffer tail offset */
+ unsigned short cm_start; /* start offset of buffer */
+ unsigned short cm_max; /* last offset of buffer */
};
/************************************************************************
* Event structure definition.
************************************************************************/
struct ev_t {
- volatile unsigned short ev_head; /* Command buffer head offset */
- volatile unsigned short ev_tail; /* Command buffer tail offset */
- volatile unsigned short ev_start; /* start offset of buffer */
- volatile unsigned short ev_max; /* last offset of buffer */
+ unsigned short ev_head; /* Command buffer head offset */
+ unsigned short ev_tail; /* Command buffer tail offset */
+ unsigned short ev_start; /* start offset of buffer */
+ unsigned short ev_max; /* last offset of buffer */
};
/************************************************************************
* Download buffer structure.
************************************************************************/
struct downld_t {
- uchar dl_type; /* Header */
- uchar dl_seq; /* Download sequence */
+ u8 dl_type; /* Header */
+ u8 dl_seq; /* Download sequence */
ushort dl_srev; /* Software revision number */
ushort dl_lrev; /* Low revision number */
ushort dl_hrev; /* High revision number */
ushort dl_seg; /* Start segment address */
ushort dl_size; /* Number of bytes to download */
- uchar dl_data[1024]; /* Download data */
+ u8 dl_data[1024]; /* Download data */
};
/************************************************************************
* U = unknown (may be changed w/o notice) *
************************************************************************/
struct bs_t {
- volatile unsigned short tp_jmp; /* Transmit poll jump */
- volatile unsigned short tc_jmp; /* Cooked procedure jump */
- volatile unsigned short ri_jmp; /* Not currently used */
- volatile unsigned short rp_jmp; /* Receive poll jump */
-
- volatile unsigned short tx_seg; /* W Tx segment */
- volatile unsigned short tx_head; /* W Tx buffer head offset */
- volatile unsigned short tx_tail; /* R Tx buffer tail offset */
- volatile unsigned short tx_max; /* W Tx buffer size - 1 */
-
- volatile unsigned short rx_seg; /* W Rx segment */
- volatile unsigned short rx_head; /* W Rx buffer head offset */
- volatile unsigned short rx_tail; /* R Rx buffer tail offset */
- volatile unsigned short rx_max; /* W Rx buffer size - 1 */
-
- volatile unsigned short tx_lw; /* W Tx buffer low water mark */
- volatile unsigned short rx_lw; /* W Rx buffer low water mark */
- volatile unsigned short rx_hw; /* W Rx buffer high water mark */
- volatile unsigned short incr; /* W Increment to next channel */
-
- volatile unsigned short fepdev; /* U SCC device base address */
- volatile unsigned short edelay; /* W Exception delay */
- volatile unsigned short blen; /* W Break length */
- volatile unsigned short btime; /* U Break complete time */
-
- volatile unsigned short iflag; /* C UNIX input flags */
- volatile unsigned short oflag; /* C UNIX output flags */
- volatile unsigned short cflag; /* C UNIX control flags */
- volatile unsigned short wfill[13]; /* U Reserved for expansion */
-
- volatile unsigned char num; /* U Channel number */
- volatile unsigned char ract; /* U Receiver active counter */
- volatile unsigned char bstat; /* U Break status bits */
- volatile unsigned char tbusy; /* W Transmit busy */
- volatile unsigned char iempty; /* W Transmit empty event enable */
- volatile unsigned char ilow; /* W Transmit low-water event enable */
- volatile unsigned char idata; /* W Receive data interrupt enable */
- volatile unsigned char eflag; /* U Host event flags */
-
- volatile unsigned char tflag; /* U Transmit flags */
- volatile unsigned char rflag; /* U Receive flags */
- volatile unsigned char xmask; /* U Transmit ready flags */
- volatile unsigned char xval; /* U Transmit ready value */
- volatile unsigned char m_stat; /* RC Modem status bits */
- volatile unsigned char m_change; /* U Modem bits which changed */
- volatile unsigned char m_int; /* W Modem interrupt enable bits */
- volatile unsigned char m_last; /* U Last modem status */
-
- volatile unsigned char mtran; /* C Unreported modem trans */
- volatile unsigned char orun; /* C Buffer overrun occurred */
- volatile unsigned char astartc; /* W Auxiliary Xon char */
- volatile unsigned char astopc; /* W Auxiliary Xoff char */
- volatile unsigned char startc; /* W Xon character */
- volatile unsigned char stopc; /* W Xoff character */
- volatile unsigned char vnextc; /* W Vnext character */
- volatile unsigned char hflow; /* C Software flow control */
-
- volatile unsigned char fillc; /* U Delay Fill character */
- volatile unsigned char ochar; /* U Saved output character */
- volatile unsigned char omask; /* U Output character mask */
-
- volatile unsigned char bfill[13]; /* U Reserved for expansion */
-
- volatile unsigned char scc[16]; /* U SCC registers */
+ unsigned short tp_jmp; /* Transmit poll jump */
+ unsigned short tc_jmp; /* Cooked procedure jump */
+ unsigned short ri_jmp; /* Not currently used */
+ unsigned short rp_jmp; /* Receive poll jump */
+
+ unsigned short tx_seg; /* W Tx segment */
+ unsigned short tx_head; /* W Tx buffer head offset */
+ unsigned short tx_tail; /* R Tx buffer tail offset */
+ unsigned short tx_max; /* W Tx buffer size - 1 */
+
+ unsigned short rx_seg; /* W Rx segment */
+ unsigned short rx_head; /* W Rx buffer head offset */
+ unsigned short rx_tail; /* R Rx buffer tail offset */
+ unsigned short rx_max; /* W Rx buffer size - 1 */
+
+ unsigned short tx_lw; /* W Tx buffer low water mark */
+ unsigned short rx_lw; /* W Rx buffer low water mark */
+ unsigned short rx_hw; /* W Rx buffer high water mark*/
+ unsigned short incr; /* W Increment to next channel*/
+
+ unsigned short fepdev; /* U SCC device base address */
+ unsigned short edelay; /* W Exception delay */
+ unsigned short blen; /* W Break length */
+ unsigned short btime; /* U Break complete time */
+
+ unsigned short iflag; /* C UNIX input flags */
+ unsigned short oflag; /* C UNIX output flags */
+ unsigned short cflag; /* C UNIX control flags */
+ unsigned short wfill[13]; /* U Reserved for expansion */
+
+ unsigned char num; /* U Channel number */
+ unsigned char ract; /* U Receiver active counter */
+ unsigned char bstat; /* U Break status bits */
+ unsigned char tbusy; /* W Transmit busy */
+ unsigned char iempty; /* W Transmit empty event */
+ /* enable */
+ unsigned char ilow; /* W Transmit low-water event */
+ /* enable */
+ unsigned char idata; /* W Receive data interrupt */
+ /* enable */
+ unsigned char eflag; /* U Host event flags */
+
+ unsigned char tflag; /* U Transmit flags */
+ unsigned char rflag; /* U Receive flags */
+ unsigned char xmask; /* U Transmit ready flags */
+ unsigned char xval; /* U Transmit ready value */
+ unsigned char m_stat; /* RC Modem status bits */
+ unsigned char m_change; /* U Modem bits which changed */
+ unsigned char m_int; /* W Modem interrupt enable */
+ /* bits */
+ unsigned char m_last; /* U Last modem status */
+
+ unsigned char mtran; /* C Unreported modem trans */
+ unsigned char orun; /* C Buffer overrun occurred */
+ unsigned char astartc; /* W Auxiliary Xon char */
+ unsigned char astopc; /* W Auxiliary Xoff char */
+ unsigned char startc; /* W Xon character */
+ unsigned char stopc; /* W Xoff character */
+ unsigned char vnextc; /* W Vnext character */
+ unsigned char hflow; /* C Software flow control */
+
+ unsigned char fillc; /* U Delay Fill character */
+ unsigned char ochar; /* U Saved output character */
+ unsigned char omask; /* U Output character mask */
+
+ unsigned char bfill[13]; /* U Reserved for expansion */
+
+ unsigned char scc[16]; /* U SCC registers */
};
struct cnode {
union {
struct {
- char type; /* Board Type */
+ char type; /* Board Type */
long port; /* I/O Address */
char *portstr; /* I/O Address in string */
long addr; /* Memory Address */
} module;
char *ttyname;
-
char *cuname;
-
char *printname;
-
long majornumber;
-
long altpin;
-
long ttysize;
-
long chsize;
-
long bssize;
-
long unsize;
-
long f2size;
-
long vpixsize;
-
long useintr;
} u;
};
-
#endif
dev->interrupt_in_buffer[6],
dev->interrupt_in_buffer[7]);
#if SUPPRESS_EXTRA_OFFLINE_EVENTS
- if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff)
- goto resubmit;
+ if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff)
+ goto resubmit;
if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) {
dev->offline = 2;
goto resubmit;
dev->offline = 1;
#endif /* SUPPRESS_EXTRA_OFFLINE_EVENTS */
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
- __func__, dev->ring_head, dev->ring_tail);
+ dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+ __func__, dev->ring_head, dev->ring_tail);
next_ring_head = (dev->ring_head + 1) % ring_buffer_size;
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
memcpy(fifo->data, src + l, n - l);
if (FAIL(fifo, addr_check(fifo->done, fifo->in, fifo->in + n) ||
- fifo->avail < n,
- "fifo corrupt: in:%u out:%u done:%u n:%d avail:%d",
- fifo->in, fifo->out, fifo->done, n, fifo->avail))
+ fifo->avail < n,
+ "fifo corrupt: in:%u out:%u done:%u n:%d avail:%d",
+ fifo->in, fifo->out, fifo->done, n, fifo->avail))
return -ENXIO;
fifo->in += n;
++fifo->open;
if (FAIL(fifo, fifo->open > fifo->open_limit,
- "past open limit:%d (limit:%d)",
- fifo->open, fifo->open_limit))
+ "past open limit:%d (limit:%d)",
+ fifo->open, fifo->open_limit))
return -ENXIO;
if (FAIL(fifo, fifo->out & (fifo->align - 1),
- "fifo out unaligned:%u (align:%u)",
- fifo->out, fifo->align))
+ "fifo out unaligned:%u (align:%u)",
+ fifo->out, fifo->align))
return -ENXIO;
return len - n;
return -EINVAL;
if (FAIL(fifo, list_empty(&fifo->pending) != (fifo->open == 0),
- "pending list disagrees with open count:%d",
- fifo->open))
+ "pending list disagrees with open count:%d",
+ fifo->open))
return -ENXIO;
tmp = complete->data;
}
if (FAIL(fifo, pending->out != fifo->done ||
- addr_check(fifo->in, fifo->done, pending->next),
- "in:%u out:%u done:%u saved:%u next:%u",
- fifo->in, fifo->out, fifo->done, pending->out,
- pending->next))
+ addr_check(fifo->in, fifo->done, pending->next),
+ "in:%u out:%u done:%u saved:%u next:%u",
+ fifo->in, fifo->out, fifo->done, pending->out,
+ pending->next))
return -ENXIO;
list_del_init(&pending->link);
if (FAIL(fifo, fifo->open < 0, "open dma:%d < 0", fifo->open))
return -ENXIO;
if (FAIL(fifo, fifo->avail > fifo->size, "fifo avail:%d > size:%d",
- fifo->avail, fifo->size))
+ fifo->avail, fifo->size))
return -ENXIO;
return 0;
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _DMA_FIFO_H_
return (unsigned long)dp->data & 1UL;
}
-extern void dma_fifo_init(struct dma_fifo *fifo);
-extern int dma_fifo_alloc(struct dma_fifo *fifo, int size, unsigned align,
- int tx_limit, int open_limit, gfp_t gfp_mask);
-extern void dma_fifo_free(struct dma_fifo *fifo);
-extern void dma_fifo_reset(struct dma_fifo *fifo);
-extern int dma_fifo_in(struct dma_fifo *fifo, const void *src, int n);
-extern int dma_fifo_out_pend(struct dma_fifo *fifo, struct dma_pending *pended);
-extern int dma_fifo_out_complete(struct dma_fifo *fifo,
- struct dma_pending *complete);
+void dma_fifo_init(struct dma_fifo *fifo);
+int dma_fifo_alloc(struct dma_fifo *fifo, int size, unsigned align,
+ int tx_limit, int open_limit, gfp_t gfp_mask);
+void dma_fifo_free(struct dma_fifo *fifo);
+void dma_fifo_reset(struct dma_fifo *fifo);
+int dma_fifo_in(struct dma_fifo *fifo, const void *src, int n);
+int dma_fifo_out_pend(struct dma_fifo *fifo, struct dma_pending *pended);
+int dma_fifo_out_complete(struct dma_fifo *fifo,
+ struct dma_pending *complete);
/* returns the # of used bytes in the fifo */
static inline int dma_fifo_level(struct dma_fifo *fifo)
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
while (n) {
t = min(n, 16);
c = tty_insert_flip_string_fixed_flag(&port->port, buf,
- TTY_BREAK, t);
+ TTY_BREAK, t);
n -= c;
brk += c;
if (c < t)
switch (tcode) {
case TCODE_WRITE_QUADLET_REQUEST:
- if (addr != port->rx_handler.offset || len != 4)
+ if (addr != port->rx_handler.offset || len != 4) {
rcode = RCODE_ADDRESS_ERROR;
- else {
+ } else {
fwtty_update_port_status(port, *(unsigned *)data);
rcode = RCODE_COMPLETE;
}
/* try to write as many dma transactions out as possible */
n = -EAGAIN;
while (!tty->stopped && !tty->hw_stopped &&
- !test_bit(STOP_TX, &port->flags)) {
+ !test_bit(STOP_TX, &port->flags)) {
txn = kmem_cache_alloc(fwtty_txn_cache, GFP_ATOMIC);
if (!txn) {
n = -ENOMEM;
if (n < 0) {
kmem_cache_free(fwtty_txn_cache, txn);
- if (n == -EAGAIN)
+ if (n == -EAGAIN) {
++port->stats.tx_stall;
- else if (n == -ENODATA)
+ } else if (n == -ENODATA) {
fwtty_profile_data(port->stats.txns, 0);
- else {
+ } else {
++port->stats.fifo_errs;
fwtty_err_ratelimited(port, "fifo err: %d\n",
n);
for (j = 0; j < num_ports; ++i, ++j) {
port_table_corrupt |= port_table[i] != ports[j];
WARN_ONCE(port_table_corrupt, "port_table[%d]: %p != ports[%d]: %p",
- i, port_table[i], j, ports[j]);
+ i, port_table[i], j, ports[j]);
port_table[i] = NULL;
}
return -EFAULT;
if (tmp.irq != 0 || tmp.port != 0 || tmp.custom_divisor != 0 ||
- tmp.baud_base != 400000000)
+ tmp.baud_base != 400000000)
return -EPERM;
if (!capable(CAP_SYS_ADMIN)) {
if (((tmp.flags & ~ASYNC_USR_MASK) !=
(port->port.flags & ~ASYNC_USR_MASK)))
return -EPERM;
- } else
+ } else {
port->port.close_delay = tmp.close_delay * HZ / 100;
+ }
return 0;
}
spin_lock_bh(&port->lock);
baud = set_termios(port, tty);
- if ((baud == 0) && (old->c_cflag & CBAUD))
+ if ((baud == 0) && (old->c_cflag & CBAUD)) {
port->mctrl &= ~(TIOCM_DTR | TIOCM_RTS);
- else if ((baud != 0) && !(old->c_cflag & CBAUD)) {
+ } else if ((baud != 0) && !(old->c_cflag & CBAUD)) {
if (C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags))
port->mctrl |= TIOCM_DTR | TIOCM_RTS;
else
rcode == RCODE_GENERATION) {
fwtty_dbg(&peer->unit, "mgmt write error: %d\n", rcode);
continue;
- } else
+ } else {
break;
+ }
} while (--tries > 0);
return rcode;
}
port->max_payload = link_speed_to_max_payload(SCODE_100);
dma_fifo_change_tx_limit(&port->tx_fifo, port->max_payload);
- rcu_assign_pointer(port->peer, NULL);
+ RCU_INIT_POINTER(port->peer, NULL);
spin_unlock_bh(&port->lock);
if (port->port.console && port->fwcon_ops->notify != NULL)
static void fwserial_plug_timeout(unsigned long data)
{
- struct fwtty_peer *peer = (struct fwtty_peer *) data;
+ struct fwtty_peer *peer = (struct fwtty_peer *)data;
struct fwtty_port *port;
spin_lock_bh(&peer->lock);
port->max_payload = link_speed_to_max_payload(SCODE_100);
dma_fifo_init(&port->tx_fifo);
- rcu_assign_pointer(port->peer, NULL);
+ RCU_INIT_POINTER(port->peer, NULL);
serial->ports[i] = port;
/* get unique bus addr region for port's status & recv fifo */
break;
case FWSC_VIRT_CABLE_UNPLUG_RSP:
- if (peer->state != FWPS_UNPLUG_PENDING)
+ if (peer->state != FWPS_UNPLUG_PENDING) {
rcode = RCODE_CONFLICT_ERROR;
- else {
+ } else {
if (be16_to_cpu(pkt->hdr.code) & FWSC_RSP_NACK)
fwtty_notice(&peer->unit, "NACK unplug?\n");
port = peer_revert_state(peer);
NAND
----
-- Switch from spinlock to mutex
- Remove excess checking of parameters in calls
- Use dma coherent memory not kmalloc/__pa for the memory (this is just
a cleanliness issue not a correctness one)
/* set number of bytes in buffer to write */
AUDIO_WRITE_BUFFER_1 = 0x10,
AUDIO_WRITE_BUFFER_2 = 0x14,
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ AUDIO_SET_WRITE_BUFFER_1_HIGH = 0x28,
+ AUDIO_SET_WRITE_BUFFER_2_HIGH = 0x30,
+#endif
/* true if audio input is supported */
AUDIO_READ_SUPPORTED = 0x18,
/* buffer to use for audio input */
AUDIO_SET_READ_BUFFER = 0x1C,
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ AUDIO_SET_READ_BUFFER_HIGH = 0x34,
+#endif
/* driver writes number of bytes to read */
AUDIO_START_READ = 0x20,
while (count > 0) {
ssize_t copy = count;
+
if (copy > WRITE_BUFFER_SIZE)
copy = WRITE_BUFFER_SIZE;
wait_event_interruptible(data->wait, (data->buffer_status &
struct resource *r;
struct goldfish_audio *data;
dma_addr_t buf_addr;
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ u32 buf_addr_high, buf_addr_low;
+#endif
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL) {
goto err_misc_register_failed;
}
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ buf_addr_low = (u32)(buf_addr);
+ buf_addr_high = (u32)((buf_addr) >> 32);
+
+ AUDIO_WRITE(data, AUDIO_SET_WRITE_BUFFER_1, buf_addr_low);
+ AUDIO_WRITE(data, AUDIO_SET_WRITE_BUFFER_1_HIGH, buf_addr_high);
+
+ buf_addr_low = (u32)(buf_addr + WRITE_BUFFER_SIZE);
+ buf_addr_high = (u32)((buf_addr + WRITE_BUFFER_SIZE) >> 32);
+
+ AUDIO_WRITE(data, AUDIO_SET_WRITE_BUFFER_2, buf_addr_low);
+ AUDIO_WRITE(data, AUDIO_SET_WRITE_BUFFER_2_HIGH, buf_addr_high);
+
+ buf_addr_low = (u32)(buf_addr + 2 * WRITE_BUFFER_SIZE);
+ buf_addr_high = (u32)((buf_addr + 2 * WRITE_BUFFER_SIZE) >> 32);
+
+ data->read_supported = AUDIO_READ(data, AUDIO_READ_SUPPORTED);
+ if (data->read_supported){
+ AUDIO_WRITE(data, AUDIO_SET_READ_BUFFER, buf_addr_low);
+ AUDIO_WRITE(data, AUDIO_SET_READ_BUFFER_HIGH, buf_addr_high);
+ }
+#else
AUDIO_WRITE(data, AUDIO_SET_WRITE_BUFFER_1, buf_addr);
AUDIO_WRITE(data, AUDIO_SET_WRITE_BUFFER_2,
buf_addr + WRITE_BUFFER_SIZE);
if (data->read_supported)
AUDIO_WRITE(data, AUDIO_SET_READ_BUFFER,
buf_addr + 2 * WRITE_BUFFER_SIZE);
+#endif
audio_data = data;
return 0;
err_misc_register_failed:
+ free_irq(data->irq, data);
err_request_irq_failed:
dma_free_coherent(&pdev->dev, COMBINED_BUFFER_SIZE,
data->buffer_virt, data->buffer_phys);
#include <linux/vmalloc.h>
#include <linux/mtd/mtd.h>
#include <linux/platform_device.h>
+#include <linux/mutex.h>
#include <asm/div64.h>
#include "goldfish_nand_reg.h"
struct goldfish_nand {
- spinlock_t lock;
+ struct mutex lock;
unsigned char __iomem *base;
struct cmd_params *cmd_params;
size_t mtd_count;
cps->addr_high = (u32)(addr >> 32);
cps->addr_low = (u32)addr;
cps->transfer_size = len;
- cps->data = (u32)ptr;
+ cps->data = (unsigned long)ptr;
writel(cmdp, base + NAND_COMMAND);
*rv = cps->result;
return 0;
{
struct goldfish_nand *nand = mtd->priv;
u32 rv;
- unsigned long irq_flags;
unsigned char __iomem *base = nand->base;
- spin_lock_irqsave(&nand->lock, irq_flags);
+ mutex_lock(&nand->lock);
if (goldfish_nand_cmd_with_params(mtd, cmd, addr, len, ptr, &rv)) {
writel(mtd - nand->mtd, base + NAND_DEV);
writel((u32)(addr >> 32), base + NAND_ADDR_HIGH);
writel((u32)addr, base + NAND_ADDR_LOW);
writel(len, base + NAND_TRANSFER_SIZE);
writel((u32)ptr, base + NAND_DATA);
+#ifdef CONFIG_64BIT
+ writel((u32)((u64)ptr >> 32), base + NAND_DATA_HIGH);
+#endif
writel(cmd, base + NAND_COMMAND);
rv = readl(base + NAND_RESULT);
}
- spin_unlock_irqrestore(&nand->lock, irq_flags);
+ mutex_unlock(&nand->lock);
return rv;
}
u32 name_len;
u32 result;
u32 flags;
- unsigned long irq_flags;
unsigned char __iomem *base = nand->base;
struct mtd_info *mtd = &nand->mtd[id];
char *name;
- spin_lock_irqsave(&nand->lock, irq_flags);
+ mutex_lock(&nand->lock);
writel(id, base + NAND_DEV);
flags = readl(base + NAND_DEV_FLAGS);
name_len = readl(base + NAND_DEV_NAME_LEN);
"goldfish nand dev%d: size %llx, page %d, extra %d, erase %d\n",
id, mtd->size, mtd->writesize,
mtd->oobsize, mtd->erasesize);
- spin_unlock_irqrestore(&nand->lock, irq_flags);
+ mutex_unlock(&nand->lock);
mtd->priv = nand;
if (nand == NULL)
return -ENOMEM;
- spin_lock_init(&nand->lock);
+ mutex_init(&nand->lock);
nand->base = base;
nand->mtd_count = num_dev;
platform_set_drvdata(pdev, nand);
{
struct goldfish_nand *nand = platform_get_drvdata(pdev);
int i;
+
for (i = 0; i < nand->mtd_count; i++) {
if (nand->mtd[i].name)
mtd_device_unregister(&nand->mtd[i]);
NAND_RESULT = 0x040,
NAND_COMMAND = 0x044,
NAND_DATA = 0x048,
+#ifdef CONFIG_64BIT
+ NAND_DATA_HIGH = 0x100,
+#endif
NAND_TRANSFER_SIZE = 0x04c,
NAND_ADDR_LOW = 0x050,
NAND_ADDR_HIGH = 0x054,
uint32_t addr_low;
uint32_t addr_high;
uint32_t transfer_size;
- uint32_t data;
+ unsigned long data;
uint32_t result;
};
#endif
gs_fpga-y += gs_fpgaboot.o io.o
obj-$(CONFIG_GS_FPGABOOT) += gs_fpga.o
-
-ccflags-$(CONFIG_GS_FPGA_DEBUG) := -DDEBUG
r = -1;
pr_info("FPGA DOWNLOAD --->\n");
- pr_info("built at %s UTC\n", __TIMESTAMP__);
pr_info("FPGA image file name: %s\n", file);
Say yes here to include parallel interface support on the AD7606
ADC driver.
-config AD799X
- tristate "Analog Devices AD799x ADC driver"
- depends on I2C
- select IIO_TRIGGER if IIO_BUFFER
- select AD799X_RING_BUFFER
- help
- Say yes here to build support for Analog Devices:
- ad7991, ad7995, ad7999, ad7992, ad7993, ad7994, ad7997, ad7998
- i2c analog to digital converters (ADC). Provides direct access
- via sysfs.
-
-config AD799X_RING_BUFFER
- bool "Analog Devices AD799x: use ring buffer"
- depends on AD799X
- select IIO_BUFFER
- select IIO_TRIGGERED_BUFFER
- help
- Say yes here to include ring buffer support in the AD799X
- ADC driver.
-
config AD7780
tristate "Analog Devices AD7780 and similar ADCs driver"
depends on SPI
ad7606-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o
obj-$(CONFIG_AD7606) += ad7606.o
-ad799x-y := ad799x_core.o
-ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o
-obj-$(CONFIG_AD799X) += ad799x.o
-
obj-$(CONFIG_AD7291) += ad7291.o
obj-$(CONFIG_AD7780) += ad7780.o
obj-$(CONFIG_AD7816) += ad7816.o
msecs = (ret >> 3) * 71500;
- return sprintf(buf, "%d\n", msecs);
+ return sprintf(buf, "%u\n", msecs);
}
static ssize_t ad7280_store_balance_timer(struct device *dev,
return -EINVAL;
}
- return sprintf(buf, "%d\n", val);
+ return sprintf(buf, "%u\n", val);
}
static ssize_t ad7280_write_channel_config(struct device *dev,
*/
/**
- * struct ad7606_platform_data - platform/board specifc information
+ * struct ad7606_platform_data - platform/board specific information
* @default_os: default oversampling value {0, 2, 4, 8, 16, 32, 64}
* @default_range: default range +/-{5000, 10000} mVolt
* @gpio_convst: number of gpio connected to the CONVST pin
};
/**
- * struct ad7606_chip_info - chip specifc information
+ * struct ad7606_chip_info - chip specific information
* @name: identification string for chip
* @int_vref_mv: the internal reference voltage
* @channels: channel specification
/*
- * struct ad7816_chip_info - chip specifc information
+ * struct ad7816_chip_info - chip specific information
*/
struct ad7816_chip_info {
+++ /dev/null
-/*
- * Copyright (C) 2010-2011 Michael Hennerich, Analog Devices Inc.
- * Copyright (C) 2008-2010 Jonathan Cameron
- *
- * 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.
- *
- * ad799x.h
- */
-
-#ifndef _AD799X_H_
-#define _AD799X_H_
-
-#define AD799X_CHANNEL_SHIFT 4
-#define AD799X_STORAGEBITS 16
-/*
- * AD7991, AD7995 and AD7999 defines
- */
-
-#define AD7991_REF_SEL 0x08
-#define AD7991_FLTR 0x04
-#define AD7991_BIT_TRIAL_DELAY 0x02
-#define AD7991_SAMPLE_DELAY 0x01
-
-/*
- * AD7992, AD7993, AD7994, AD7997 and AD7998 defines
- */
-
-#define AD7998_FLTR 0x08
-#define AD7998_ALERT_EN 0x04
-#define AD7998_BUSY_ALERT 0x02
-#define AD7998_BUSY_ALERT_POL 0x01
-
-#define AD7998_CONV_RES_REG 0x0
-#define AD7998_ALERT_STAT_REG 0x1
-#define AD7998_CONF_REG 0x2
-#define AD7998_CYCLE_TMR_REG 0x3
-
-#define AD7998_DATALOW_REG(x) ((x) * 3 + 0x4)
-#define AD7998_DATAHIGH_REG(x) ((x) * 3 + 0x5)
-#define AD7998_HYST_REG(x) ((x) * 3 + 0x6)
-
-#define AD7998_CYC_MASK 0x7
-#define AD7998_CYC_DIS 0x0
-#define AD7998_CYC_TCONF_32 0x1
-#define AD7998_CYC_TCONF_64 0x2
-#define AD7998_CYC_TCONF_128 0x3
-#define AD7998_CYC_TCONF_256 0x4
-#define AD7998_CYC_TCONF_512 0x5
-#define AD7998_CYC_TCONF_1024 0x6
-#define AD7998_CYC_TCONF_2048 0x7
-
-#define AD7998_ALERT_STAT_CLEAR 0xFF
-
-/*
- * AD7997 and AD7997 defines
- */
-
-#define AD7997_8_READ_SINGLE 0x80
-#define AD7997_8_READ_SEQUENCE 0x70
-/* TODO: move this into a common header */
-#define RES_MASK(bits) ((1 << (bits)) - 1)
-
-enum {
- ad7991,
- ad7995,
- ad7999,
- ad7992,
- ad7993,
- ad7994,
- ad7997,
- ad7998
-};
-
-struct ad799x_state;
-
-/**
- * struct ad799x_chip_info - chip specifc information
- * @channel: channel specification
- * @num_channels: number of channels
- * @monitor_mode: whether the chip supports monitor interrupts
- * @default_config: device default configuration
- * @event_attrs: pointer to the monitor event attribute group
- */
-
-struct ad799x_chip_info {
- struct iio_chan_spec channel[9];
- int num_channels;
- u16 default_config;
- const struct iio_info *info;
-};
-
-struct ad799x_state {
- struct i2c_client *client;
- const struct ad799x_chip_info *chip_info;
- struct regulator *reg;
- struct regulator *vref;
- unsigned id;
- u16 config;
-
- u8 *rx_buf;
- unsigned int transfer_size;
-};
-
-#ifdef CONFIG_AD799X_RING_BUFFER
-int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev);
-void ad799x_ring_cleanup(struct iio_dev *indio_dev);
-#else /* CONFIG_AD799X_RING_BUFFER */
-
-static inline int
-ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return 0;
-}
-
-static inline void ad799x_ring_cleanup(struct iio_dev *indio_dev)
-{
-}
-#endif /* CONFIG_AD799X_RING_BUFFER */
-#endif /* _AD799X_H_ */
+++ /dev/null
-/*
- * Copyright (C) 2010-2012 Michael Hennerich, Analog Devices Inc.
- * Copyright (C) 2008-2010 Jonathan Cameron
- *
- * 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.
- *
- * ad799x_ring.c
- */
-
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/i2c.h>
-#include <linux/bitops.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/triggered_buffer.h>
-
-#include "ad799x.h"
-
-/**
- * ad799x_trigger_handler() bh of trigger launched polling to ring buffer
- *
- * Currently there is no option in this driver to disable the saving of
- * timestamps within the ring.
- **/
-
-static irqreturn_t ad799x_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct ad799x_state *st = iio_priv(indio_dev);
- int b_sent;
- u8 cmd;
-
- switch (st->id) {
- case ad7991:
- case ad7995:
- case ad7999:
- cmd = st->config |
- (*indio_dev->active_scan_mask << AD799X_CHANNEL_SHIFT);
- break;
- case ad7992:
- case ad7993:
- case ad7994:
- cmd = (*indio_dev->active_scan_mask << AD799X_CHANNEL_SHIFT) |
- AD7998_CONV_RES_REG;
- break;
- case ad7997:
- case ad7998:
- cmd = AD7997_8_READ_SEQUENCE | AD7998_CONV_RES_REG;
- break;
- default:
- cmd = 0;
- }
-
- b_sent = i2c_smbus_read_i2c_block_data(st->client,
- cmd, st->transfer_size, st->rx_buf);
- if (b_sent < 0)
- goto out;
-
- iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
- iio_get_time_ns());
-out:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
-{
- return iio_triggered_buffer_setup(indio_dev, NULL,
- &ad799x_trigger_handler, NULL);
-}
-
-void ad799x_ring_cleanup(struct iio_dev *indio_dev)
-{
- iio_triggered_buffer_cleanup(indio_dev);
-}
struct resource *iores;
int ret = 0, touch_ret;
int i, s;
- unsigned int scale_uv;
+ uint64_t scale_uv;
/* Allocate the IIO device. */
iio = devm_iio_device_alloc(dev, sizeof(*lradc));
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
-/*
- * SPEAR registers definitions
- */
-
-#define SCAN_RATE_LO(x) ((x) & 0xFFFF)
-#define SCAN_RATE_HI(x) (((x) >> 0x10) & 0xFFFF)
-#define CLK_LOW(x) (((x) & 0xf) << 0)
-#define CLK_HIGH(x) (((x) & 0xf) << 4)
+/* SPEAR registers definitions */
+#define SPEAR600_ADC_SCAN_RATE_LO(x) ((x) & 0xFFFF)
+#define SPEAR600_ADC_SCAN_RATE_HI(x) (((x) >> 0x10) & 0xFFFF)
+#define SPEAR_ADC_CLK_LOW(x) (((x) & 0xf) << 0)
+#define SPEAR_ADC_CLK_HIGH(x) (((x) & 0xf) << 4)
/* Bit definitions for SPEAR_ADC_STATUS */
-#define START_CONVERSION (1 << 0)
-#define CHANNEL_NUM(x) ((x) << 1)
-#define ADC_ENABLE (1 << 4)
-#define AVG_SAMPLE(x) ((x) << 5)
-#define VREF_INTERNAL (1 << 9)
+#define SPEAR_ADC_STATUS_START_CONVERSION (1 << 0)
+#define SPEAR_ADC_STATUS_CHANNEL_NUM(x) ((x) << 1)
+#define SPEAR_ADC_STATUS_ADC_ENABLE (1 << 4)
+#define SPEAR_ADC_STATUS_AVG_SAMPLE(x) ((x) << 5)
+#define SPEAR_ADC_STATUS_VREF_INTERNAL (1 << 9)
-#define DATA_MASK 0x03ff
-#define DATA_BITS 10
+#define SPEAR_ADC_DATA_MASK 0x03ff
+#define SPEAR_ADC_DATA_BITS 10
-#define MOD_NAME "spear-adc"
+#define SPEAR_ADC_MOD_NAME "spear-adc"
-#define ADC_CHANNEL_NUM 8
+#define SPEAR_ADC_CHANNEL_NUM 8
-#define CLK_MIN 2500000
-#define CLK_MAX 20000000
+#define SPEAR_ADC_CLK_MIN 2500000
+#define SPEAR_ADC_CLK_MAX 20000000
struct adc_regs_spear3xx {
u32 status;
u32 average;
u32 scan_rate;
u32 clk; /* Not avail for 1340 & 1310 */
- u32 ch_ctrl[ADC_CHANNEL_NUM];
- u32 ch_data[ADC_CHANNEL_NUM];
+ u32 ch_ctrl[SPEAR_ADC_CHANNEL_NUM];
+ u32 ch_data[SPEAR_ADC_CHANNEL_NUM];
};
struct chan_data {
u32 status;
u32 pad[2];
u32 clk;
- u32 ch_ctrl[ADC_CHANNEL_NUM];
- struct chan_data ch_data[ADC_CHANNEL_NUM];
+ u32 ch_ctrl[SPEAR_ADC_CHANNEL_NUM];
+ struct chan_data ch_data[SPEAR_ADC_CHANNEL_NUM];
u32 scan_rate_lo;
u32 scan_rate_hi;
struct chan_data average;
};
-struct spear_adc_info {
+struct spear_adc_state {
struct device_node *np;
struct adc_regs_spear3xx __iomem *adc_base_spear3xx;
struct adc_regs_spear6xx __iomem *adc_base_spear6xx;
* static inline functions, because of different register offsets
* on different SoC variants (SPEAr300 vs SPEAr600 etc).
*/
-static void spear_adc_set_status(struct spear_adc_info *info, u32 val)
+static void spear_adc_set_status(struct spear_adc_state *st, u32 val)
{
- __raw_writel(val, &info->adc_base_spear6xx->status);
+ __raw_writel(val, &st->adc_base_spear6xx->status);
}
-static void spear_adc_set_clk(struct spear_adc_info *info, u32 val)
+static void spear_adc_set_clk(struct spear_adc_state *st, u32 val)
{
u32 clk_high, clk_low, count;
- u32 apb_clk = clk_get_rate(info->clk);
+ u32 apb_clk = clk_get_rate(st->clk);
count = (apb_clk + val - 1) / val;
clk_low = count / 2;
clk_high = count - clk_low;
- info->current_clk = apb_clk / count;
+ st->current_clk = apb_clk / count;
- __raw_writel(CLK_LOW(clk_low) | CLK_HIGH(clk_high),
- &info->adc_base_spear6xx->clk);
+ __raw_writel(SPEAR_ADC_CLK_LOW(clk_low) | SPEAR_ADC_CLK_HIGH(clk_high),
+ &st->adc_base_spear6xx->clk);
}
-static void spear_adc_set_ctrl(struct spear_adc_info *info, int n,
+static void spear_adc_set_ctrl(struct spear_adc_state *st, int n,
u32 val)
{
- __raw_writel(val, &info->adc_base_spear6xx->ch_ctrl[n]);
+ __raw_writel(val, &st->adc_base_spear6xx->ch_ctrl[n]);
}
-static u32 spear_adc_get_average(struct spear_adc_info *info)
+static u32 spear_adc_get_average(struct spear_adc_state *st)
{
- if (of_device_is_compatible(info->np, "st,spear600-adc")) {
- return __raw_readl(&info->adc_base_spear6xx->average.msb) &
- DATA_MASK;
+ if (of_device_is_compatible(st->np, "st,spear600-adc")) {
+ return __raw_readl(&st->adc_base_spear6xx->average.msb) &
+ SPEAR_ADC_DATA_MASK;
} else {
- return __raw_readl(&info->adc_base_spear3xx->average) &
- DATA_MASK;
+ return __raw_readl(&st->adc_base_spear3xx->average) &
+ SPEAR_ADC_DATA_MASK;
}
}
-static void spear_adc_set_scanrate(struct spear_adc_info *info, u32 rate)
+static void spear_adc_set_scanrate(struct spear_adc_state *st, u32 rate)
{
- if (of_device_is_compatible(info->np, "st,spear600-adc")) {
- __raw_writel(SCAN_RATE_LO(rate),
- &info->adc_base_spear6xx->scan_rate_lo);
- __raw_writel(SCAN_RATE_HI(rate),
- &info->adc_base_spear6xx->scan_rate_hi);
+ if (of_device_is_compatible(st->np, "st,spear600-adc")) {
+ __raw_writel(SPEAR600_ADC_SCAN_RATE_LO(rate),
+ &st->adc_base_spear6xx->scan_rate_lo);
+ __raw_writel(SPEAR600_ADC_SCAN_RATE_HI(rate),
+ &st->adc_base_spear6xx->scan_rate_hi);
} else {
- __raw_writel(rate, &info->adc_base_spear3xx->scan_rate);
+ __raw_writel(rate, &st->adc_base_spear3xx->scan_rate);
}
}
-static int spear_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val,
- int *val2,
- long mask)
+static int spear_adc_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long mask)
{
- struct spear_adc_info *info = iio_priv(indio_dev);
+ struct spear_adc_state *st = iio_priv(indio_dev);
u32 status;
switch (mask) {
case IIO_CHAN_INFO_RAW:
mutex_lock(&indio_dev->mlock);
- status = CHANNEL_NUM(chan->channel) |
- AVG_SAMPLE(info->avg_samples) |
- START_CONVERSION | ADC_ENABLE;
- if (info->vref_external == 0)
- status |= VREF_INTERNAL;
+ status = SPEAR_ADC_STATUS_CHANNEL_NUM(chan->channel) |
+ SPEAR_ADC_STATUS_AVG_SAMPLE(st->avg_samples) |
+ SPEAR_ADC_STATUS_START_CONVERSION |
+ SPEAR_ADC_STATUS_ADC_ENABLE;
+ if (st->vref_external == 0)
+ status |= SPEAR_ADC_STATUS_VREF_INTERNAL;
- spear_adc_set_status(info, status);
- wait_for_completion(&info->completion); /* set by ISR */
- *val = info->value;
+ spear_adc_set_status(st, status);
+ wait_for_completion(&st->completion); /* set by ISR */
+ *val = st->value;
mutex_unlock(&indio_dev->mlock);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- *val = info->vref_external;
- *val2 = DATA_BITS;
+ *val = st->vref_external;
+ *val2 = SPEAR_ADC_DATA_BITS;
return IIO_VAL_FRACTIONAL_LOG2;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = st->current_clk;
+ return IIO_VAL_INT;
}
return -EINVAL;
}
+static int spear_adc_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val,
+ int val2,
+ long mask)
+{
+ struct spear_adc_state *st = iio_priv(indio_dev);
+ int ret = 0;
+
+ if (mask != IIO_CHAN_INFO_SAMP_FREQ)
+ return -EINVAL;
+
+ mutex_lock(&indio_dev->mlock);
+
+ if ((val < SPEAR_ADC_CLK_MIN) ||
+ (val > SPEAR_ADC_CLK_MAX) ||
+ (val2 != 0)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ spear_adc_set_clk(st, val);
+
+out:
+ mutex_unlock(&indio_dev->mlock);
+ return ret;
+}
+
#define SPEAR_ADC_CHAN(idx) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.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),\
.channel = idx, \
- .scan_type = { \
- .sign = 'u', \
- .storagebits = 16, \
- }, \
}
static const struct iio_chan_spec spear_adc_iio_channels[] = {
static irqreturn_t spear_adc_isr(int irq, void *dev_id)
{
- struct spear_adc_info *info = (struct spear_adc_info *)dev_id;
+ struct spear_adc_state *st = (struct spear_adc_state *)dev_id;
/* Read value to clear IRQ */
- info->value = spear_adc_get_average(info);
- complete(&info->completion);
+ st->value = spear_adc_get_average(st);
+ complete(&st->completion);
return IRQ_HANDLED;
}
-static int spear_adc_configure(struct spear_adc_info *info)
+static int spear_adc_configure(struct spear_adc_state *st)
{
int i;
/* Reset ADC core */
- spear_adc_set_status(info, 0);
- __raw_writel(0, &info->adc_base_spear6xx->clk);
+ spear_adc_set_status(st, 0);
+ __raw_writel(0, &st->adc_base_spear6xx->clk);
for (i = 0; i < 8; i++)
- spear_adc_set_ctrl(info, i, 0);
- spear_adc_set_scanrate(info, 0);
+ spear_adc_set_ctrl(st, i, 0);
+ spear_adc_set_scanrate(st, 0);
- spear_adc_set_clk(info, info->sampling_freq);
+ spear_adc_set_clk(st, st->sampling_freq);
return 0;
}
-static ssize_t spear_adc_read_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct spear_adc_info *info = iio_priv(indio_dev);
-
- return sprintf(buf, "%d\n", info->current_clk);
-}
-
-static ssize_t spear_adc_write_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 spear_adc_info *info = iio_priv(indio_dev);
- u32 clk_high, clk_low, count;
- u32 apb_clk = clk_get_rate(info->clk);
- unsigned long lval;
- int ret;
-
- ret = kstrtoul(buf, 10, &lval);
- if (ret)
- return ret;
-
- mutex_lock(&indio_dev->mlock);
-
- if ((lval < CLK_MIN) || (lval > CLK_MAX)) {
- ret = -EINVAL;
- goto out;
- }
-
- count = (apb_clk + lval - 1) / lval;
- clk_low = count / 2;
- clk_high = count - clk_low;
- info->current_clk = apb_clk / count;
- spear_adc_set_clk(info, lval);
-
-out:
- mutex_unlock(&indio_dev->mlock);
-
- return ret ? ret : len;
-}
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
- spear_adc_read_frequency,
- spear_adc_write_frequency);
-
-static struct attribute *spear_attributes[] = {
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group spear_attribute_group = {
- .attrs = spear_attributes,
-};
-
-static const struct iio_info spear_adc_iio_info = {
- .read_raw = &spear_read_raw,
- .attrs = &spear_attribute_group,
+static const struct iio_info spear_adc_info = {
+ .read_raw = &spear_adc_read_raw,
+ .write_raw = &spear_adc_write_raw,
.driver_module = THIS_MODULE,
};
{
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
- struct spear_adc_info *info;
- struct iio_dev *iodev = NULL;
+ struct spear_adc_state *st;
+ struct iio_dev *indio_dev = NULL;
int ret = -ENODEV;
int irq;
- iodev = devm_iio_device_alloc(dev, sizeof(struct spear_adc_info));
- if (!iodev) {
+ indio_dev = devm_iio_device_alloc(dev, sizeof(struct spear_adc_state));
+ if (!indio_dev) {
dev_err(dev, "failed allocating iio device\n");
return -ENOMEM;
}
- info = iio_priv(iodev);
- info->np = np;
+ st = iio_priv(indio_dev);
+ st->np = np;
/*
* SPEAr600 has a different register layout than other SPEAr SoC's
* (e.g. SPEAr3xx). Let's provide two register base addresses
* to support multi-arch kernels.
*/
- info->adc_base_spear6xx = of_iomap(np, 0);
- if (!info->adc_base_spear6xx) {
+ st->adc_base_spear6xx = of_iomap(np, 0);
+ if (!st->adc_base_spear6xx) {
dev_err(dev, "failed mapping memory\n");
return -ENOMEM;
}
- info->adc_base_spear3xx =
- (struct adc_regs_spear3xx __iomem *)info->adc_base_spear6xx;
+ st->adc_base_spear3xx =
+ (struct adc_regs_spear3xx __iomem *)st->adc_base_spear6xx;
- info->clk = clk_get(dev, NULL);
- if (IS_ERR(info->clk)) {
+ st->clk = clk_get(dev, NULL);
+ if (IS_ERR(st->clk)) {
dev_err(dev, "failed getting clock\n");
goto errout1;
}
- ret = clk_prepare_enable(info->clk);
+ ret = clk_prepare_enable(st->clk);
if (ret) {
dev_err(dev, "failed enabling clock\n");
goto errout2;
goto errout3;
}
- ret = devm_request_irq(dev, irq, spear_adc_isr, 0, MOD_NAME, info);
+ ret = devm_request_irq(dev, irq, spear_adc_isr, 0, SPEAR_ADC_MOD_NAME,
+ st);
if (ret < 0) {
dev_err(dev, "failed requesting interrupt\n");
goto errout3;
}
if (of_property_read_u32(np, "sampling-frequency",
- &info->sampling_freq)) {
+ &st->sampling_freq)) {
dev_err(dev, "sampling-frequency missing in DT\n");
ret = -EINVAL;
goto errout3;
* Optional avg_samples defaults to 0, resulting in single data
* conversion
*/
- of_property_read_u32(np, "average-samples", &info->avg_samples);
+ of_property_read_u32(np, "average-samples", &st->avg_samples);
/*
* Optional vref_external defaults to 0, resulting in internal vref
* selection
*/
- of_property_read_u32(np, "vref-external", &info->vref_external);
+ of_property_read_u32(np, "vref-external", &st->vref_external);
- spear_adc_configure(info);
+ spear_adc_configure(st);
- platform_set_drvdata(pdev, iodev);
+ platform_set_drvdata(pdev, indio_dev);
- init_completion(&info->completion);
+ init_completion(&st->completion);
- iodev->name = MOD_NAME;
- iodev->dev.parent = dev;
- iodev->info = &spear_adc_iio_info;
- iodev->modes = INDIO_DIRECT_MODE;
- iodev->channels = spear_adc_iio_channels;
- iodev->num_channels = ARRAY_SIZE(spear_adc_iio_channels);
+ indio_dev->name = SPEAR_ADC_MOD_NAME;
+ indio_dev->dev.parent = dev;
+ indio_dev->info = &spear_adc_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = spear_adc_iio_channels;
+ indio_dev->num_channels = ARRAY_SIZE(spear_adc_iio_channels);
- ret = iio_device_register(iodev);
+ ret = iio_device_register(indio_dev);
if (ret)
goto errout3;
return 0;
errout3:
- clk_disable_unprepare(info->clk);
+ clk_disable_unprepare(st->clk);
errout2:
- clk_put(info->clk);
+ clk_put(st->clk);
errout1:
- iounmap(info->adc_base_spear6xx);
+ iounmap(st->adc_base_spear6xx);
return ret;
}
static int spear_adc_remove(struct platform_device *pdev)
{
- struct iio_dev *iodev = platform_get_drvdata(pdev);
- struct spear_adc_info *info = iio_priv(iodev);
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct spear_adc_state *st = iio_priv(indio_dev);
- iio_device_unregister(iodev);
- clk_disable_unprepare(info->clk);
- clk_put(info->clk);
- iounmap(info->adc_base_spear6xx);
+ iio_device_unregister(indio_dev);
+ clk_disable_unprepare(st->clk);
+ clk_put(st->clk);
+ iounmap(st->adc_base_spear6xx);
return 0;
}
.probe = spear_adc_probe,
.remove = spear_adc_remove,
.driver = {
- .name = MOD_NAME,
+ .name = SPEAR_ADC_MOD_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(spear_adc_dt_ids),
},
#define ID_ADT75XX 0x10
/*
- * struct adt7316_chip_info - chip specifc information
+ * struct adt7316_chip_info - chip specific information
*/
struct adt7316_chip_info {
(ADT7316_TEMP_INT_MASK)
/*
- * struct adt7316_chip_info - chip specifc information
+ * struct adt7316_chip_info - chip specific information
*/
struct adt7316_limit_regs {
};
/*
- * struct ad7152_chip_info - chip specifc information
+ * struct ad7152_chip_info - chip specific information
*/
struct ad7152_chip_info {
#define AD7746_CAPDAC_DACP(x) ((x) & 0x7F)
/*
- * struct ad7746_chip_info - chip specifc information
+ * struct ad7746_chip_info - chip specific information
*/
struct ad7746_chip_info {
/* select register to write */
ret = i2c_smbus_write_byte(client, (TSL258X_CMD_REG | reg));
if (ret < 0) {
- dev_err(&client->dev, "taos_i2c_read failed to write"
- " register %x\n", reg);
+ dev_err(&client->dev,
+ "taos_i2c_read failed to write register %x\n",
+ reg);
return ret;
}
/* read the data */
if (chip->taos_chip_status != TSL258X_CHIP_WORKING) {
/* device is not enabled */
dev_err(&chip->client->dev, "taos_get_lux device is not enabled\n");
- ret = -EBUSY ;
+ ret = -EBUSY;
goto out_unlock;
}
int reg = TSL258X_CMD_REG | (TSL258X_ALS_CHAN0LO + i);
ret = taos_i2c_read(chip->client, reg, &buf[i], 1);
if (ret < 0) {
- dev_err(&chip->client->dev, "taos_get_lux failed to read"
- " register %x\n", reg);
+ dev_err(&chip->client->dev,
+ "taos_get_lux failed to read register %x\n",
+ reg);
goto out_unlock;
}
}
}
}
- msleep(3);
+ usleep_range(3000, 3500);
/* NOW enable the ADC
* initialize the desired mode of operation */
utmp = TSL258X_CNTL_PWR_ON | TSL258X_CNTL_ADC_ENBL;
if (!i2c_check_functionality(clientp->adapter,
I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_err(&clientp->dev,
- "taos_probe() - i2c smbus byte data "
- "functions unsupported\n");
+ dev_err(&clientp->dev, "taos_probe() - i2c smbus byte data func unsupported\n");
return -EOPNOTSUPP;
}
ret = i2c_smbus_write_byte(clientp,
(TSL258X_CMD_REG | (TSL258X_CNTRL + i)));
if (ret < 0) {
- dev_err(&clientp->dev, "i2c_smbus_write_bytes() to cmd "
- "reg failed in taos_probe(), err = %d\n", ret);
+ dev_err(&clientp->dev,
+ "i2c_smbus_write_byte to cmd reg failed in taos_probe(), err = %d\n",
+ ret);
return ret;
}
ret = i2c_smbus_read_byte(clientp);
if (ret < 0) {
- dev_err(&clientp->dev, "i2c_smbus_read_byte from "
- "reg failed in taos_probe(), err = %d\n", ret);
-
+ dev_err(&clientp->dev,
+ "i2c_smbus_read_byte from reg failed in taos_probe(), err = %d\n",
+ ret);
return ret;
}
buf[i] = ret;
}
if (!taos_tsl258x_device(buf)) {
- dev_info(&clientp->dev, "i2c device found but does not match "
- "expected id in taos_probe()\n");
+ dev_info(&clientp->dev,
+ "i2c device found but does not match expected id in taos_probe()\n");
return -EINVAL;
}
ret = i2c_smbus_write_byte(clientp, (TSL258X_CMD_REG | TSL258X_CNTRL));
if (ret < 0) {
- dev_err(&clientp->dev, "i2c_smbus_write_byte() to cmd reg "
- "failed in taos_probe(), err = %d\n", ret);
+ dev_err(&clientp->dev,
+ "i2c_smbus_write_byte() to cmd reg failed in taos_probe(), err = %d\n",
+ ret);
return ret;
}
vel = (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4);
vel = (vel << 4) >> 4;
*val = vel;
+ break;
default:
mutex_unlock(&st->lock);
return -EINVAL;
struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig);
if (trig_info->frequency == 0)
return -EINVAL;
- printk(KERN_INFO "trigger frequency is %d\n", trig_info->frequency);
+ dev_info(&trig_info->rtc->dev, "trigger frequency is %d\n",
+ trig_info->frequency);
return rtc_irq_set_state(trig_info->rtc, &trig_info->task, state);
}
of_node_put(port);
if (port == imx_crtc->port) {
ret = of_graph_parse_endpoint(ep, &endpoint);
- return ret ? ret : endpoint.id;
+ return ret ? ret : endpoint.port;
}
} while (ep);
struct clk *isfr_clk;
struct clk *iahb_clk;
- enum drm_connector_status connector_status;
-
struct hdmi_data_info hdmi_data;
int vic;
static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec)
{
- unsigned char val = 0;
- val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3;
- while (!val) {
- udelay(1000);
+ while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
if (msec-- == 0)
return false;
- val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3;
+ udelay(1000);
}
return true;
}
{
struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
connector);
- return hdmi->connector_status;
+
+ return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
+ connector_status_connected : connector_status_disconnected;
}
static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);
- hdmi->connector_status = connector_status_connected;
imx_hdmi_poweron(hdmi);
} else {
dev_dbg(hdmi->dev, "EVENT=plugout\n");
hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
HDMI_PHY_POL0);
- hdmi->connector_status = connector_status_disconnected;
imx_hdmi_poweroff(hdmi);
}
drm_helper_hpd_irq_event(hdmi->connector.dev);
return -ENOMEM;
hdmi->dev = dev;
- hdmi->connector_status = connector_status_disconnected;
hdmi->sample_rate = 48000;
hdmi->ratio = 100;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
- return -EINVAL;
+ return irq;
ret = devm_request_threaded_irq(dev, irq, imx_hdmi_hardirq,
imx_hdmi_irq, IRQF_SHARED,
status &= ipu_cm_read(ipu, IPU_INT_CTRL(regs[i]));
for_each_set_bit(bit, &status, 32) {
- irq = irq_linear_revmap(ipu->domain, regs[i] * 32 + bit);
+ irq = irq_linear_revmap(ipu->domain,
+ regs[i] * 32 + bit);
if (irq)
generic_handle_irq(irq);
}
}
ret = irq_alloc_domain_generic_chips(ipu->domain, 32, 1, "IPU",
- handle_level_irq, 0, IRQF_VALID, 0);
+ handle_level_irq, 0,
+ IRQF_VALID, 0);
if (ret < 0) {
dev_err(ipu->dev, "failed to alloc generic irq chips\n");
irq_domain_remove(ipu->domain);
IPU_DC_MAP_RGB565,
IPU_DC_MAP_GBR24, /* TVEv2 */
IPU_DC_MAP_BGR666,
+ IPU_DC_MAP_LVDS666,
IPU_DC_MAP_BGR24,
};
return IPU_DC_MAP_GBR24;
case V4L2_PIX_FMT_BGR666:
return IPU_DC_MAP_BGR666;
+ case v4l2_fourcc('L', 'V', 'D', '6'):
+ return IPU_DC_MAP_LVDS666;
case V4L2_PIX_FMT_BGR24:
return IPU_DC_MAP_BGR24;
default:
writel(DC_WR_CH_CONF_WORD_SIZE_24 | DC_WR_CH_CONF_DISP_ID_PARALLEL(0),
priv->channels[5].base + DC_WR_CH_CONF);
- writel(DC_GEN_SYNC_1_6_SYNC | DC_GEN_SYNC_PRIORITY_1, priv->dc_reg + DC_GEN);
+ writel(DC_GEN_SYNC_1_6_SYNC | DC_GEN_SYNC_PRIORITY_1,
+ priv->dc_reg + DC_GEN);
ipu->dc_priv = priv;
ipu_dc_map_config(priv, IPU_DC_MAP_BGR666, 1, 11, 0xfc); /* green */
ipu_dc_map_config(priv, IPU_DC_MAP_BGR666, 2, 17, 0xfc); /* red */
+ /* lvds666 */
+ ipu_dc_map_clear(priv, IPU_DC_MAP_LVDS666);
+ ipu_dc_map_config(priv, IPU_DC_MAP_LVDS666, 0, 5, 0xfc); /* blue */
+ ipu_dc_map_config(priv, IPU_DC_MAP_LVDS666, 1, 13, 0xfc); /* green */
+ ipu_dc_map_config(priv, IPU_DC_MAP_LVDS666, 2, 21, 0xfc); /* red */
+
/* bgr24 */
ipu_dc_map_clear(priv, IPU_DC_MAP_BGR24);
ipu_dc_map_config(priv, IPU_DC_MAP_BGR24, 2, 7, 0xff); /* red */
imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB565;
else if (!strcmp(fmt, "bgr666"))
imxpd->interface_pix_fmt = V4L2_PIX_FMT_BGR666;
+ else if (!strcmp(fmt, "lvds666"))
+ imxpd->interface_pix_fmt = v4l2_fourcc('L', 'V', 'D', '6');
}
panel_node = of_parse_phandle(np, "fsl,panel", 0);
#include "usb.h"
#include "scsiglue.h"
#include "transport.h"
+#include "smil.h"
#include "init.h"
/*
#include "common.h"
extern u32 MediaChange;
-extern int Check_D_MediaFmt(struct us_data *);
int Init_D_SmartMedia(void);
int Pwoff_D_SmartMedia(void);
int Check_D_SmartMedia(void);
+int Check_D_MediaFmt(struct us_data *);
int Check_D_Parameter(struct us_data *, u16 *, u8 *, u8 *);
int Media_D_ReadSector(struct us_data *, u32, u16, u8 *);
int Media_D_WriteSector(struct us_data *, u32, u16, u8 *);
int _Correct_D_SwECC(u8 *, u8 *, u8 *);
void _Calculate_D_SwECC(u8 *, u8 *);
-void SM_Init(void);
-
#endif /* already included */
void Set_D_FailBlock(u8 *redundant)
{
char i;
+
for (i = 0; i < REDTSIZE; i++)
*redundant++ = (u8)((i == REDT_BLOCK) ? 0xF0 : 0xFF);
}
/* R/W data */
if (transfer_length) {
unsigned int pipe;
+
if (srb->sc_data_direction == DMA_FROM_DEVICE)
pipe = us->recv_bulk_pipe;
else
static int line6_start_listen(struct usb_line6 *line6)
{
int err;
+
usb_fill_int_urb(line6->urb_listen, line6->usbdev,
usb_rcvintpipe(line6->usbdev, line6->ep_control_read),
line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
MISSING_CASE;
}
- line6pcm = kzalloc(sizeof(struct snd_line6_pcm), GFP_KERNEL);
+ line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL);
if (line6pcm == NULL)
return -ENOMEM;
if (bytes_per_frame == 4) {
short *p, *buf_end;
+
p = (short *)urb_out->transfer_buffer;
buf_end = p + urb_out->transfer_buffer_length / sizeof(*p);
for (; p < buf_end; p += 3) {
int val;
+
val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16);
val = (val * volume[chn & 1]) >> 8;
p[0] = val;
if (bytes_per_frame == 4) {
short *pi, *po, *buf_end;
+
pi = (short *)signal;
po = (short *)urb_out->transfer_buffer;
buf_end = po + urb_out->transfer_buffer_length / sizeof(*po);
if (fsize == 0) {
int n;
+
line6pcm->count_out += frame_increment;
n = line6pcm->count_out / frame_factor;
line6pcm->count_out -= n * frame_factor;
copy the data to the temp buffer.
*/
int len;
+
len = runtime->buffer_size - line6pcm->pos_out;
if (len > 0) {
struct snd_ctl_elem_info *uinfo)
{
const int size = ARRAY_SIZE(toneport_source_info);
+
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = size;
/* check if task is running in compat mode.*/
#define current_pid() (current->pid)
#define current_comm() (current->comm)
-int cfs_get_environ(const char *key, char *value, int *val_len);
typedef __u32 cfs_cap_t;
#endif
#include <linux/libcfs/linux/libcfs.h>
+#include <linux/gfp.h>
#include "curproc.h"
int
cfs_cpt_number(struct cfs_cpt_table *cptab);
/**
- * return number of HW cores or hypter-threadings in a CPU partition \a cpt
+ * return number of HW cores or hyper-threadings in a CPU partition \a cpt
*/
int cfs_cpt_weight(struct cfs_cpt_table *cptab, int cpt);
/**
*/
int cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt);
/**
- * add \a cpu to CPU partion @cpt of \a cptab, return 1 for success,
+ * add \a cpu to CPU partition @cpt of \a cptab, return 1 for success,
* otherwise 0 is returned
*/
int cfs_cpt_set_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu);
*/
int cfs_cpt_spread_node(struct cfs_cpt_table *cptab, int cpt);
+/**
+ * return number of HTs in the same core of \a cpu
+ */
+int cfs_cpu_ht_nsiblings(int cpu);
+
/**
* iterate over all CPU partitions in \a cptab
*/
struct cfs_crypto_hash_type {
char *cht_name; /**< hash algorithm name, equal to
* format name for crypto api */
- unsigned int cht_key; /**< init key by default (vaild for
+ unsigned int cht_key; /**< init key by default (valid for
* 4 bytes context like crc32, adler */
unsigned int cht_size; /**< hash digest size */
};
do { \
(data)->msg_subsys = DEBUG_SUBSYSTEM; \
(data)->msg_file = __FILE__; \
- (data)->msg_fn = __FUNCTION__; \
+ (data)->msg_fn = __func__; \
(data)->msg_line = __LINE__; \
(data)->msg_cdls = (cdls); \
(data)->msg_mask = (mask); \
static struct libcfs_debug_msg_data dataname = { \
.msg_subsys = DEBUG_SUBSYSTEM, \
.msg_file = __FILE__, \
- .msg_fn = __FUNCTION__, \
+ .msg_fn = __func__, \
.msg_line = __LINE__, \
.msg_cdls = (cdls) }; \
dataname.msg_mask = (mask);
/*
* Ideally we would use HAVE_HASH_LONG for this, but on linux we configure
* the linux kernel and user space at the same time, so we need to differentiate
- * between them explicitely. If this is not needed on other architectures, then
- * we'll need to move the functions to archi specific headers.
+ * between them explicitly. If this is not needed on other architectures, then
+ * we'll need to move the functions to architecture specific headers.
*/
#include <linux/hash.h>
/**
* cfs_hash_bucket is a container of:
- * - lock, couter ...
+ * - lock, counter ...
* - array of hash-head starting from hsb_head[0], hash-head can be one of
* . cfs_hash_head_t
* . cfs_hash_head_dep_t
CFS_HASH_NO_BKTLOCK = 1 << 1,
/** rwlock to protect bucket */
CFS_HASH_RW_BKTLOCK = 1 << 2,
- /** spinlcok to protect bucket */
+ /** spinlock to protect bucket */
CFS_HASH_SPIN_BKTLOCK = 1 << 3,
/** always add new item to tail */
CFS_HASH_ADD_TAIL = 1 << 4,
* default allocator
*/
#define LIBCFS_ALLOC(ptr, size) \
- LIBCFS_ALLOC_GFP(ptr, size, __GFP_IO)
+ LIBCFS_ALLOC_GFP(ptr, size, GFP_NOFS)
/**
* non-sleeping allocator
/** default numa allocator */
#define LIBCFS_CPT_ALLOC(ptr, cptab, cpt, size) \
- LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, __GFP_IO)
+ LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, GFP_NOFS)
#define LIBCFS_FREE(ptr, size) \
do { \
* - spin_unlock(x)
* - spin_unlock_bh(x)
* - spin_trylock(x)
- * - spin_is_locked(x)
+ * - assert_spin_locked(x)
*
* - spin_lock_irq(x)
* - spin_lock_irqsave(x, f)
#include <linux/memcontrol.h>
#include <linux/mm_inline.h>
+#ifndef HAVE_LIBCFS_CPT
+/* Need this for cfs_cpt_table */
+#include <linux/libcfs/libcfs_cpu.h>
+#endif
+
#define CFS_PAGE_MASK (~((__u64)PAGE_CACHE_SIZE-1))
#define page_index(p) ((p)->index)
#define MAX_PORTALS 64
/* these are only used by code with LNET_USE_LIB_FREELIST, but we still
- * exported them to !LNET_USE_LIB_FREELIST for easy implemetation */
+ * exported them to !LNET_USE_LIB_FREELIST for easy implementation */
#define LNET_FL_MAX_MES 2048
#define LNET_FL_MAX_MDS 2048
#define LNET_FL_MAX_EQS 512
unsigned int msg_receiving:1; /* being received */
unsigned int msg_txcredit:1; /* taken an NI send credit */
unsigned int msg_peertxcredit:1; /* taken a peer send credit */
- unsigned int msg_rtrcredit:1; /* taken a globel router credit */
+ unsigned int msg_rtrcredit:1; /* taken a global router credit */
unsigned int msg_peerrtrcredit:1; /* taken a peer router credit */
unsigned int msg_onactivelist:1; /* on the activelist */
/* Start receiving 'mlen' bytes of payload data, skipping the following
* 'rlen' - 'mlen' bytes. 'private' is the 'private' passed to
- * lnet_parse(). Return non-zero for immedaite failure, otherwise
+ * lnet_parse(). Return non-zero for immediate failure, otherwise
* complete later with lnet_finalize(). This also gives back a receive
* credit if the LND does flow control. */
int (*lnd_recv)(struct lnet_ni *ni, void *private, lnet_msg_t *msg,
unsigned int mt_cpt;
unsigned int mt_portal; /* portal index */
/* match table is set as "enabled" if there's non-exhausted MD
- * attached on mt_mhash, it's only valide for wildcard portal */
+ * attached on mt_mhash, it's only valid for wildcard portal */
unsigned int mt_enabled;
/* bitmap to flag whether MEs on mt_hash are exhausted or not */
__u64 mt_exhausted[LNET_MT_EXHAUSTED_BMAP];
/* add stat in session */
typedef struct {
int lstio_sta_key; /* IN: session key */
- int lstio_sta_timeout; /* IN: timeout for stat requst */
+ int lstio_sta_timeout; /* IN: timeout for stat request */
int lstio_sta_nmlen; /* IN: group name length */
char *lstio_sta_namep; /* IN: group name */
int lstio_sta_count; /* IN: # of pid */
/*#define PTL_MD_LUSTRE_COMPLETION_SEMANTICS */
/* Can compare handles directly on Cray Portals */
-#define PtlHandleIsEqual(a,b) ((a) == (b))
+#define PtlHandleIsEqual(a, b) ((a) == (b))
/* Different error types on Cray Portals*/
#define ptl_err_t ptl_ni_fail_t
* above is for bulk data transfer */
#define LNET_MSG_MATCHBITS 0 /* the value for the message channel */
-typedef struct
-{
+typedef struct {
lnet_hdr_t kptlim_hdr; /* portals header */
char kptlim_payload[0]; /* piggy-backed payload */
} WIRE_ATTR kptl_immediate_msg_t;
-typedef struct
-{
+typedef struct {
lnet_hdr_t kptlrm_hdr; /* portals header */
__u64 kptlrm_matchbits; /* matchbits */
} WIRE_ATTR kptl_rdma_msg_t;
-typedef struct
-{
+typedef struct {
__u64 kptlhm_matchbits; /* matchbits */
__u32 kptlhm_max_msg_size; /* max message size */
} WIRE_ATTR kptl_hello_msg_t;
-typedef struct
-{
+typedef struct {
/* First 2 fields fixed FOR ALL TIME */
__u32 ptlm_magic; /* I'm a Portals LND message */
__u16 ptlm_version; /* this is my version number */
} kptl_msg_t;
/* kptl_msg_t::ptlm_credits is only a __u8 */
-#define PTLLND_MSG_MAX_CREDITS ((typeof(((kptl_msg_t*) 0)->ptlm_credits)) -1)
+#define PTLLND_MSG_MAX_CREDITS ((typeof(((kptl_msg_t*) 0)->ptlm_credits)) - 1)
#define PTLLND_MSG_MAGIC LNET_PROTO_PTL_MAGIC
#define PTLLND_MSG_VERSION 0x04
*/
static inline int LNetHandleIsEqual (lnet_handle_any_t h1, lnet_handle_any_t h2)
{
- return (h1.cookie == h2.cookie);
+ return h1.cookie == h2.cookie;
}
/**
*/
static inline int LNetHandleIsInvalid(lnet_handle_any_t h)
{
- return (LNET_WIRE_HANDLE_COOKIE_NONE == h.cookie);
+ return LNET_WIRE_HANDLE_COOKIE_NONE == h.cookie;
}
/**
* address of an array of lnet_kiov_t and the length field specifies
* the number of entries in the array. The length can't be bigger
* than LNET_MAX_IOV. The lnet_kiov_t is used to describe page-based
- * fragments that are not necessarily mapped in virtal memory.
+ * fragments that are not necessarily mapped in virtual memory.
* - LNET_MD_IOVEC bit set: The start field points to the starting
* address of an array of struct iovec and the length field specifies
* the number of entries in the array. The length can't be bigger
#define LNET_SEQ_BASETYPE long
typedef unsigned LNET_SEQ_BASETYPE lnet_seq_t;
-#define LNET_SEQ_GT(a,b) (((signed LNET_SEQ_BASETYPE)((a) - (b))) > 0)
+#define LNET_SEQ_GT(a, b) (((signed LNET_SEQ_BASETYPE)((a) - (b))) > 0)
/**
* Information about an event on a MD.
for (i = 0; i < npages; i++) {
p->ibp_pages[i] = alloc_pages_node(
cfs_cpt_spread_node(lnet_cpt_table(), cpt),
- __GFP_IO, 0);
+ GFP_NOFS, 0);
if (p->ibp_pages[i] == NULL) {
CERROR("Can't allocate page %d of %d\n", i, npages);
kiblnd_free_pages(p);
case IBLND_REJECT_MSG_QUEUE_SIZE:
CERROR("%s rejected: incompatible message queue depth %d, %d\n",
- libcfs_nid2str(peer->ibp_nid), cp->ibcp_queue_depth,
+ libcfs_nid2str(peer->ibp_nid),
+ cp != NULL ? cp->ibcp_queue_depth :
+ IBLND_MSG_QUEUE_SIZE(rej->ibr_version),
IBLND_MSG_QUEUE_SIZE(conn->ibc_version));
break;
case IBLND_REJECT_RDMA_FRAGS:
CERROR("%s rejected: incompatible # of RDMA fragments %d, %d\n",
- libcfs_nid2str(peer->ibp_nid), cp->ibcp_max_frags,
+ libcfs_nid2str(peer->ibp_nid),
+ cp != NULL ? cp->ibcp_max_frags :
+ IBLND_RDMA_FRAGS(rej->ibr_version),
IBLND_RDMA_FRAGS(conn->ibc_version));
break;
ip = peer->ksnp_passive_ips[i];
best_iface = ksocknal_ip2iface(peer->ksnp_ni, ip);
- /* peer passive ips are kept up to date */
- LASSERT(best_iface != NULL);
} else {
/* choose a new interface */
LASSERT (i == peer->ksnp_n_passive_ips);
peer->ksnp_n_passive_ips = i+1;
}
- LASSERT (best_iface != NULL);
-
/* mark the best matching peer IP used */
j = ksocknal_match_peerip(best_iface, peerips, n_peerips);
peerips[j] = 0;
ksocknal_lib_eager_ack (ksock_conn_t *conn)
{
int opt = 1;
- mm_segment_t oldmm = get_fs();
struct socket *sock = conn->ksnc_sock;
/* Remind the socket to ACK eagerly. If I don't, the socket might
* on, introducing delay in completing zero-copy sends in my
* peer. */
- set_fs(KERNEL_DS);
- sock->ops->setsockopt (sock, SOL_TCP, TCP_QUICKACK,
+ kernel_setsockopt(sock, SOL_TCP, TCP_QUICKACK,
(char *)&opt, sizeof (opt));
- set_fs(oldmm);
}
int
int
ksocknal_lib_get_conn_tunables (ksock_conn_t *conn, int *txmem, int *rxmem, int *nagle)
{
- mm_segment_t oldmm = get_fs ();
struct socket *sock = conn->ksnc_sock;
int len;
int rc;
rc = libcfs_sock_getbuf(sock, txmem, rxmem);
if (rc == 0) {
len = sizeof(*nagle);
- set_fs(KERNEL_DS);
- rc = sock->ops->getsockopt(sock, SOL_TCP, TCP_NODELAY,
+ rc = kernel_getsockopt(sock, SOL_TCP, TCP_NODELAY,
(char *)nagle, &len);
- set_fs(oldmm);
}
ksocknal_connsock_decref(conn);
int
ksocknal_lib_setup_sock (struct socket *sock)
{
- mm_segment_t oldmm = get_fs ();
int rc;
int option;
int keep_idle;
linger.l_onoff = 0;
linger.l_linger = 0;
- set_fs (KERNEL_DS);
- rc = sock_setsockopt (sock, SOL_SOCKET, SO_LINGER,
+ rc = kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER,
(char *)&linger, sizeof (linger));
- set_fs (oldmm);
if (rc != 0) {
CERROR ("Can't set SO_LINGER: %d\n", rc);
return (rc);
}
option = -1;
- set_fs (KERNEL_DS);
- rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_LINGER2,
+ rc = kernel_setsockopt(sock, SOL_TCP, TCP_LINGER2,
(char *)&option, sizeof (option));
- set_fs (oldmm);
if (rc != 0) {
CERROR ("Can't set SO_LINGER2: %d\n", rc);
return (rc);
if (!*ksocknal_tunables.ksnd_nagle) {
option = 1;
- set_fs (KERNEL_DS);
- rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_NODELAY,
+ rc = kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY,
(char *)&option, sizeof (option));
- set_fs (oldmm);
if (rc != 0) {
CERROR ("Can't disable nagle: %d\n", rc);
return (rc);
do_keepalive = (keep_idle > 0 && keep_count > 0 && keep_intvl > 0);
option = (do_keepalive ? 1 : 0);
- set_fs (KERNEL_DS);
- rc = sock_setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE,
+ rc = kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
(char *)&option, sizeof (option));
- set_fs (oldmm);
if (rc != 0) {
CERROR ("Can't set SO_KEEPALIVE: %d\n", rc);
return (rc);
if (!do_keepalive)
return (0);
- set_fs (KERNEL_DS);
- rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_KEEPIDLE,
+ rc = kernel_setsockopt(sock, SOL_TCP, TCP_KEEPIDLE,
(char *)&keep_idle, sizeof (keep_idle));
- set_fs (oldmm);
if (rc != 0) {
CERROR ("Can't set TCP_KEEPIDLE: %d\n", rc);
return (rc);
}
- set_fs (KERNEL_DS);
- rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_KEEPINTVL,
+ rc = kernel_setsockopt(sock, SOL_TCP, TCP_KEEPINTVL,
(char *)&keep_intvl, sizeof (keep_intvl));
- set_fs (oldmm);
if (rc != 0) {
CERROR ("Can't set TCP_KEEPINTVL: %d\n", rc);
return (rc);
}
- set_fs (KERNEL_DS);
- rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_KEEPCNT,
+ rc = kernel_setsockopt(sock, SOL_TCP, TCP_KEEPCNT,
(char *)&keep_count, sizeof (keep_count));
- set_fs (oldmm);
if (rc != 0) {
CERROR ("Can't set TCP_KEEPCNT: %d\n", rc);
return (rc);
int nonagle;
int val = 1;
int rc;
- mm_segment_t oldmm;
rc = ksocknal_connsock_addref(conn);
if (rc != 0) /* being shut down */
tp->nonagle = 1;
release_sock (sk);
- oldmm = get_fs ();
- set_fs (KERNEL_DS);
-
- rc = sk->sk_prot->setsockopt (sk, SOL_TCP, TCP_NODELAY,
+ rc = kernel_setsockopt(conn->ksnc_sock, SOL_TCP, TCP_NODELAY,
(char *)&val, sizeof (val));
LASSERT (rc == 0);
- set_fs (oldmm);
-
lock_sock (sk);
tp->nonagle = nonagle;
release_sock (sk);
static void
lnet_destroy_remote_nets_table(void)
{
- int i;
- struct list_head *hash;
+ int i;
if (the_lnet.ln_remote_nets_hash == NULL)
return;
LASSERT(list_empty(&the_lnet.ln_remote_nets_hash[i]));
LIBCFS_FREE(the_lnet.ln_remote_nets_hash,
- LNET_REMOTE_NETS_HASH_SIZE * sizeof(*hash));
+ LNET_REMOTE_NETS_HASH_SIZE *
+ sizeof(the_lnet.ln_remote_nets_hash[0]));
the_lnet.ln_remote_nets_hash = NULL;
}
counters->send_count += ctr->send_count;
counters->recv_count += ctr->recv_count;
counters->route_count += ctr->route_count;
- counters->drop_length += ctr->drop_length;
+ counters->drop_count += ctr->drop_count;
counters->send_length += ctr->send_length;
counters->recv_length += ctr->recv_length;
counters->route_length += ctr->route_length;
break;
}
- while (!list_empty(&ni->ni_list)) {
+ if (!list_empty(&ni->ni_list)) {
lnet_net_unlock(LNET_LOCK_EX);
++i;
if ((i & (-i)) == i) {
- CDEBUG(D_WARNING,
- "Waiting for zombie LNI %s\n",
+ CDEBUG(D_WARNING, "Waiting for zombie LNI %s\n",
libcfs_nid2str(ni->ni_nid));
}
set_current_state(TASK_UNINTERRUPTIBLE);
libcfs_nid2str(ni->ni_nid));
lnet_ni_free(ni);
+ i = 2;
+
lnet_net_lock(LNET_LOCK_EX);
}
* NB individual events can be missed; the only guarantee is that you
* always get the most recent news */
- if (lp->lp_notifying)
+ if (lp->lp_notifying || ni == NULL)
return;
lp->lp_notifying = 1;
#include <lustre_fid.h>
#include "fid_internal.h"
+/* Format: [0x64BIT_INT - 0x64BIT_INT] + 32 bytes just in case */
+#define MAX_FID_RANGE_STRLEN (32 + 2 * 2 * sizeof(__u64))
/*
* Note: this function is only used for testing, it is no safe for production
* use.
*/
-static int
-lprocfs_fid_write_common(const char *buffer, unsigned long count,
- struct lu_seq_range *range)
+static int lprocfs_fid_write_common(const char __user *buffer, size_t count,
+ struct lu_seq_range *range)
{
struct lu_seq_range tmp;
int rc;
+ char kernbuf[MAX_FID_RANGE_STRLEN];
LASSERT(range != NULL);
- rc = sscanf(buffer, "[%llx - %llx]\n",
+ if (count >= sizeof(kernbuf))
+ return -EINVAL;
+
+ if (copy_from_user(kernbuf, buffer, count))
+ return -EFAULT;
+
+ kernbuf[count] = 0;
+
+ if (count == 5 && strcmp(kernbuf, "clear") == 0) {
+ memset(range, 0, sizeof(*range));
+ return count;
+ }
+
+ /* of the form "[0x0000000240000400 - 0x000000028000400]" */
+ rc = sscanf(kernbuf, "[%llx - %llx]\n",
(long long unsigned *)&tmp.lsr_start,
(long long unsigned *)&tmp.lsr_end);
- if (rc != 2 || !range_is_sane(&tmp) || range_is_zero(&tmp))
+ if (!range_is_sane(&tmp) || range_is_zero(&tmp) ||
+ tmp.lsr_start < range->lsr_start || tmp.lsr_end > range->lsr_end)
return -EINVAL;
*range = tmp;
- return 0;
+ return count;
}
/* Client side procfs stuff */
-static ssize_t
-lprocfs_fid_space_seq_write(struct file *file, const char *buffer,
- size_t count, loff_t *off)
+static ssize_t lprocfs_fid_space_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
{
struct lu_client_seq *seq = ((struct seq_file *)file->private_data)->private;
int rc;
return rc;
}
-static ssize_t
-lprocfs_fid_width_seq_write(struct file *file, const char *buffer,
- size_t count, loff_t *off)
+static ssize_t lprocfs_fid_width_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
{
struct lu_client_seq *seq = ((struct seq_file *)file->private_data)->private;
__u64 max;
struct dt_object *dt,
struct lustre_capa *old,
__u64 opc);
- int (*do_object_sync)(const struct lu_env *, struct dt_object *);
+ int (*do_object_sync)(const struct lu_env *env, struct dt_object *obj,
+ __u64 start, __u64 end);
/**
* Get object info of next level. Currently, only get inode from osd.
* This is only used by quota b=16542
int dt_lookup_dir(const struct lu_env *env, struct dt_object *dir,
const char *name, struct lu_fid *fid);
-static inline int dt_object_sync(const struct lu_env *env,
- struct dt_object *o)
+static inline int dt_object_sync(const struct lu_env *env, struct dt_object *o,
+ __u64 start, __u64 end)
{
LASSERT(o);
LASSERT(o->do_ops);
LASSERT(o->do_ops->do_object_sync);
- return o->do_ops->do_object_sync(env, o);
+ return o->do_ops->do_object_sync(env, o, start, end);
}
int dt_declare_version_set(const struct lu_env *env, struct dt_object *o,
+++ /dev/null
-/*
- * 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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2003, 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 _IOWR
-
-/* On i386 and x86_64, _ASM_I386_IOCTL_H is defined by the kernel's ioctl.h,
- * and on newer kernels this header is shared as _ASM_GENERIC_IOCTL_H.
- *
- * We can avoid any problems with the kernel header being included again by
- * defining _ASM_I386_IOCTL_H here so that a later occurrence of <asm/ioctl.h>
- * does not include the kernel's ioctl.h after this one. b=14746 */
-#define _ASM_I386_IOCTL_H
-#define _ASM_GENERIC_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms. The i386 ioctl numbering scheme doesn't really enforce
- * a type field. De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here. Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS 8
-#define _IOC_TYPEBITS 8
-#define _IOC_SIZEBITS 14
-#define _IOC_DIRBITS 2
-
-#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT 0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE 0U
-#define _IOC_WRITE 1U
-#define _IOC_READ 2U
-
-#define _IOC(dir,type,nr,size) (((dir) << _IOC_DIRSHIFT) | ((type) << _IOC_TYPESHIFT) | ((nr) << _IOC_NRSHIFT) | ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
-
-#endif /* _IOWR */
}
#define client_obd_list_lock(lock) \
- __client_obd_list_lock(lock, __FUNCTION__, __LINE__)
+ __client_obd_list_lock(lock, __func__, __LINE__)
static inline void client_obd_list_unlock(client_obd_lock_t *lock)
{
#define JOBSTATS_JOBID_VAR_MAX_LEN 20
#define JOBSTATS_DISABLE "disable"
#define JOBSTATS_PROCNAME_UID "procname_uid"
+#define JOBSTATS_NODELOCAL "nodelocal"
extern int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
int *val, int mult);
{ \
return single_open(file, name##_seq_show, PDE_DATA(inode)); \
} \
-struct file_operations name##_fops = { \
+static struct file_operations name##_fops = { \
.owner = THIS_MODULE, \
.open = name##_single_open, \
.read = seq_read, \
{ \
return single_open(file, NULL, PDE_DATA(inode)); \
} \
- struct file_operations name##_##type##_fops = { \
+ static struct file_operations name##_##type##_fops = { \
.open = name##_##type##_open, \
.write = name##_##type##_write, \
.release = lprocfs_single_release, \
* whether object is backed by persistent storage entity.
*/
struct lu_object_header {
+ /**
+ * Fid, uniquely identifying this object.
+ */
+ struct lu_fid loh_fid;
/**
* Object flags from enum lu_object_header_flags. Set and checked
* atomically.
* Object reference count. Protected by lu_site::ls_guard.
*/
atomic_t loh_ref;
- /**
- * Fid, uniquely identifying this object.
- */
- struct lu_fid loh_fid;
/**
* Common object attributes, cached for efficiency. From enum
* lu_object_header_attr.
*
* // current thread acquired a temporary reference to foo.
* foo_get(foo);
- * lu_ref_add(&foo->reference, __FUNCTION__, current);
+ * lu_ref_add(&foo->reference, __func__, current);
*
* ...
*
* // temporary reference is released.
- * lu_ref_del(&foo->reference, __FUNCTION__, current);
+ * lu_ref_del(&foo->reference, __func__, current);
* foo_put(foo);
* \endcode
*
static inline void range_init(struct lu_seq_range *range)
{
- range->lsr_start = range->lsr_end = range->lsr_index = 0;
+ memset(range, 0, sizeof(*range));
}
/**
stripes * sizeof(struct lov_ost_data_v1);
}
+static inline __u32
+lov_mds_md_max_stripe_count(size_t buf_size, __u32 lmm_magic)
+{
+ switch (lmm_magic) {
+ case LOV_MAGIC_V1: {
+ struct lov_mds_md_v1 lmm;
+
+ if (buf_size < sizeof(lmm))
+ return 0;
+
+ return (buf_size - sizeof(lmm)) / sizeof(lmm.lmm_objects[0]);
+ }
+ case LOV_MAGIC_V3: {
+ struct lov_mds_md_v3 lmm;
+
+ if (buf_size < sizeof(lmm))
+ return 0;
+
+ return (buf_size - sizeof(lmm)) / sizeof(lmm.lmm_objects[0]);
+ }
+ default:
+ return 0;
+ }
+}
#define OBD_MD_FLID (0x00000001ULL) /* object ID */
#define OBD_MD_FLATIME (0x00000002ULL) /* access time */
* protocol, this will limit the max number of OSTs per LOV */
#define LOV_DESC_MAGIC 0xB0CCDE5C
+#define LOV_DESC_QOS_MAXAGE_DEFAULT 5 /* Seconds */
+#define LOV_DESC_STRIPE_SIZE_DEFAULT (1 << LNET_MTU_BITS)
/* LOV settings descriptor (should only contain static info) */
struct lov_desc {
{
return (struct hsm_action_item *)(hal->hal_fsname +
cfs_size_round(strlen(hal-> \
- hal_fsname)));
+ hal_fsname)
+ + 1));
}
/* Return pointer to next hai */
static inline struct hsm_action_item * hai_next(struct hsm_action_item *hai)
int i, sz;
struct hsm_action_item *hai;
- sz = sizeof(*hal) + cfs_size_round(strlen(hal->hal_fsname));
+ sz = sizeof(*hal) + cfs_size_round(strlen(hal->hal_fsname) + 1);
hai = hai_zero(hal);
for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai))
sz += cfs_size_round(hai->hai_len);
/* lib/debug.c */
void dump_lniobuf(struct niobuf_local *lnb);
int dump_req(struct ptlrpc_request *req);
-void dump_lsm(int level, struct lov_stripe_md *lsm);
int block_debug_setup(void *addr, int len, __u64 off, __u64 id);
int block_debug_check(char *who, void *addr, int len, __u64 off, __u64 id);
int (*po_recalc)(struct ldlm_pool *pl);
/** Cancel at least \a nr locks from pool \a pl */
int (*po_shrink)(struct ldlm_pool *pl, int nr,
- unsigned int gfp_mask);
+ gfp_t gfp_mask);
int (*po_setup)(struct ldlm_pool *pl, int limit);
};
/** Recalculation period for pool. */
time_t pl_recalc_period;
/** Recalculation and shrink operations. */
- struct ldlm_pool_ops *pl_ops;
+ const struct ldlm_pool_ops *pl_ops;
/** Number of planned locks for next period. */
int pl_grant_plan;
/** Pool statistics. */
const struct ldlm_res_id *);
#define LDLM_RESOURCE_ADDREF(res) do { \
- lu_ref_add_atomic(&(res)->lr_reference, __FUNCTION__, current); \
+ lu_ref_add_atomic(&(res)->lr_reference, __func__, current); \
} while (0)
#define LDLM_RESOURCE_DELREF(res) do { \
- lu_ref_del(&(res)->lr_reference, __FUNCTION__, current); \
+ lu_ref_del(&(res)->lr_reference, __func__, current); \
} while (0)
/* ldlm_request.c */
/** Check if resource is already locked, assert if not. */
static inline void check_res_locked(struct ldlm_resource *res)
{
- LASSERT(spin_is_locked(&res->lr_lock));
+ assert_spin_locked(&res->lr_lock);
}
struct ldlm_resource * lock_res_and_lock(struct ldlm_lock *lock);
int ldlm_pool_init(struct ldlm_pool *pl, struct ldlm_namespace *ns,
int idx, ldlm_side_t client);
int ldlm_pool_shrink(struct ldlm_pool *pl, int nr,
- unsigned int gfp_mask);
+ gfp_t gfp_mask);
void ldlm_pool_fini(struct ldlm_pool *pl);
int ldlm_pool_setup(struct ldlm_pool *pl, int limit);
int ldlm_pool_recalc(struct ldlm_pool *pl);
void statfs_pack(struct obd_statfs *osfs, struct kstatfs *sfs);
void statfs_unpack(struct kstatfs *sfs, struct obd_statfs *osfs);
-/* l_lock.c */
-struct lustre_lock {
- int l_depth;
- struct task_struct *l_owner;
- struct semaphore l_sem;
- spinlock_t l_spin;
-};
-
-void l_lock_init(struct lustre_lock *);
-void l_lock(struct lustre_lock *);
-void l_unlock(struct lustre_lock *);
-int l_has_lock(struct lustre_lock *);
-
/*
* For md echo client
*/
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");
+ 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 > (1<<30)) {
- CERROR("OBD ioctl: ioc_inllen1 larger than 1<<30\n");
+ if (data->ioc_inllen1 > OBD_MAX_IOCTL_BUFFER) {
+ CERROR("OBD ioctl: ioc_inllen1 larger than ioc_len\n");
return 1;
}
- if (data->ioc_inllen2 > (1<<30)) {
- CERROR("OBD ioctl: ioc_inllen2 larger than 1<<30\n");
+ if (data->ioc_inllen2 > OBD_MAX_IOCTL_BUFFER) {
+ CERROR("OBD ioctl: ioc_inllen2 larger than ioc_len\n");
return 1;
}
- if (data->ioc_inllen3 > (1<<30)) {
- CERROR("OBD ioctl: ioc_inllen3 larger than 1<<30\n");
+ if (data->ioc_inllen3 > OBD_MAX_IOCTL_BUFFER) {
+ CERROR("OBD ioctl: ioc_inllen3 larger than ioc_len\n");
return 1;
}
- if (data->ioc_inllen4 > (1<<30)) {
- CERROR("OBD ioctl: ioc_inllen4 larger than 1<<30\n");
+ 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) {
int __llog_ctxt_put(const struct lu_env *env, struct llog_ctxt *ctxt);
int llog_cleanup(const struct lu_env *env, struct llog_ctxt *);
int llog_sync(struct llog_ctxt *ctxt, struct obd_export *exp, int flags);
-int llog_obd_add(const struct lu_env *env, struct llog_ctxt *ctxt,
- struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
- struct llog_cookie *logcookies, int numcookies);
int llog_cancel(const struct lu_env *env, struct llog_ctxt *ctxt,
- struct lov_stripe_md *lsm, int count,
struct llog_cookie *cookies, int flags);
int obd_llog_init(struct obd_device *obd, struct obd_llog_group *olg,
int flags);
int (*lop_cleanup)(const struct lu_env *env, struct llog_ctxt *ctxt);
int (*lop_cancel)(const struct lu_env *env, struct llog_ctxt *ctxt,
- struct lov_stripe_md *lsm, int count,
struct llog_cookie *cookies, int flags);
int (*lop_connect)(struct llog_ctxt *ctxt, struct llog_logid *logid,
struct llog_gen *gen, struct obd_uuid *uuid);
int (*lop_add)(const struct lu_env *env, struct llog_handle *lgh,
struct llog_rec_hdr *rec, struct llog_cookie *cookie,
void *buf, struct thandle *th);
- /* Old llog_add version, used in MDS-LOV-OSC now and will gone with
- * LOD/OSP replacement */
- int (*lop_obd_add)(const struct lu_env *env, struct llog_ctxt *ctxt,
- struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
- struct llog_cookie *logcookies, int numcookies);
};
/* In-memory descriptor for a log object or log catalog */
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.
+ */
static inline void mdc_update_max_ea_from_body(struct obd_export *exp,
struct mdt_body *body)
{
if (body->valid & OBD_MD_FLMODEASIZE) {
- if (exp->exp_obd->u.cli.cl_max_mds_easize < body->max_mdsize)
- exp->exp_obd->u.cli.cl_max_mds_easize =
- body->max_mdsize;
- if (exp->exp_obd->u.cli.cl_max_mds_cookiesize <
- body->max_cookiesize)
- exp->exp_obd->u.cli.cl_max_mds_cookiesize =
- body->max_cookiesize;
+ struct client_obd *cli = &exp->exp_obd->u.cli;
+
+ 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_CACHE_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_CACHE_SIZE);
+ }
}
}
#define LDLM_MAXREQSIZE (5 * 1024)
#define LDLM_MAXREPSIZE (1024)
+#define MDS_MAXREQSIZE (5 * 1024) /* >= 4736 */
+
#define OST_MAXREQSIZE (5 * 1024)
/* Macro to hide a typecast. */
* \a nrq
* \param[in,out] nrq The request
*
- * \pre spin_is_locked(&svcpt->scp_req_lock)
+ * \pre assert_spin_locked(&svcpt->scp_req_lock)
*
* \see ptlrpc_nrs_req_stop_nolock()
*/
return true;
}
+static inline int lov_stripe_md_size(unsigned int stripe_count)
+{
+ struct lov_stripe_md lsm;
+
+ return sizeof(lsm) + stripe_count * sizeof(lsm.lsm_oinfo[0]);
+}
+
struct obd_info;
typedef int (*obd_enqueue_update_f)(void *cookie, int rc);
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. */
- int cl_default_mds_easize;
- int cl_max_mds_easize;
- int cl_max_mds_cookiesize;
+ int cl_default_mds_easize;
+ int cl_max_mds_easize;
+ int cl_default_mds_cookiesize;
+ int cl_max_mds_cookiesize;
enum lustre_sec_part cl_sp_me;
enum lustre_sec_part cl_sp_to;
struct mdc_rpc_lock *cl_close_lock;
/* mgc datastruct */
- struct semaphore cl_mgc_sem;
+ struct mutex cl_mgc_mutex;
struct local_oid_storage *cl_mgc_los;
struct dt_object *cl_mgc_configs_dir;
atomic_t cl_mgc_refcount;
int max_easize;
int max_def_easize;
int max_cookiesize;
+ int max_def_cookiesize;
int server_timeout;
int tgts_size; /* size of tgts array */
#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_MAX_EASIZE "max_easize"
+#define KEY_DEFAULT_EASIZE "default_easize"
+#define KEY_MAX_COOKIESIZE "max_cookiesize"
+#define KEY_DEFAULT_COOKIESIZE "default_cookiesize"
#define KEY_MDS_CONN "mds_conn"
#define KEY_MGSSEC "mgssec"
#define KEY_NEXT_ID "next_id"
const char *, int, int, int,
struct ptlrpc_request **);
- int (*m_init_ea_size)(struct obd_export *, int, int, int);
+ int (*m_init_ea_size)(struct obd_export *, int, int, int, int);
int (*m_get_lustre_md)(struct obd_export *, struct ptlrpc_request *,
struct obd_export *, struct obd_export *,
return obd_packmd(exp, NULL, mem_src);
}
-/* helper functions */
-static inline int obd_alloc_diskmd(struct obd_export *exp,
- struct lov_mds_md **disk_tgt)
-{
- LASSERT(disk_tgt);
- LASSERT(*disk_tgt == NULL);
- return obd_packmd(exp, disk_tgt, NULL);
-}
-
static inline int obd_free_diskmd(struct obd_export *exp,
struct lov_mds_md **disk_tgt)
{
}
static inline int md_init_ea_size(struct obd_export *exp, int easize,
- int def_asize, int cookiesize)
+ int def_asize, int cookiesize,
+ int def_cookiesize)
{
EXP_CHECK_MD_OP(exp, init_ea_size);
EXP_MD_COUNTER_INCREMENT(exp, init_ea_size);
return MDP(exp->exp_obd, init_ea_size)(exp, easize, def_asize,
- cookiesize);
+ cookiesize, def_cookiesize);
}
static inline int md_get_remote_perm(struct obd_export *exp,
#define OBDO_ALLOC(ptr) \
do { \
- OBD_SLAB_ALLOC_PTR_GFP((ptr), obdo_cachep, __GFP_IO); \
+ OBD_SLAB_ALLOC_PTR_GFP((ptr), obdo_cachep, GFP_NOFS); \
} while(0)
#define OBDO_FREE(ptr) \
int mea_name2idx(struct lmv_stripe_md *mea, const char *name, int namelen);
int raw_name2idx(int hashtype, int count, const char *name, int namelen);
+/* class_obd.c */
+extern char obd_jobid_node[];
+
/* prng.c */
#define ll_generate_random_uuid(uuid_out) cfs_get_random_bytes(uuid_out, sizeof(class_uuid_t))
+++ /dev/null
-/*
- * 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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef _OBD_LOV_H__
-#define _OBD_LOV_H__
-
-#define LOV_DEFAULT_STRIPE_SIZE (1 << LNET_MTU_BITS)
-
-static inline int lov_stripe_md_size(__u16 stripes)
-{
- return sizeof(struct lov_stripe_md) + stripes*sizeof(struct lov_oinfo*);
-}
-
-struct lov_version_size {
- __u32 lvs_magic;
- size_t lvs_lmm_size;
- size_t lvs_lod_size;
-};
-
-static inline __u32 lov_mds_md_stripecnt(int ea_size, __u32 lmm_magic)
-{
- static const struct lov_version_size lmm_ver_size[] = {
- { .lvs_magic = LOV_MAGIC_V3,
- .lvs_lmm_size = sizeof(struct lov_mds_md_v3),
- .lvs_lod_size = sizeof(struct lov_ost_data_v1) },
- { .lvs_magic = LOV_MAGIC_V1,
- .lvs_lmm_size = sizeof(struct lov_mds_md_v1),
- .lvs_lod_size = sizeof(struct lov_ost_data_v1)} };
- int i;
-
- for (i = 0; i < ARRAY_SIZE(lmm_ver_size); i++) {
- if (lmm_magic == lmm_ver_size[i].lvs_magic) {
- if (ea_size <= lmm_ver_size[i].lvs_lmm_size)
- return 0;
- return (ea_size - lmm_ver_size[i].lvs_lmm_size) /
- lmm_ver_size[i].lvs_lod_size;
- }
- }
-
- /* Invalid LOV magic, so no stripes could fit */
- return 0;
-}
-
-/* lov_do_div64(a, b) returns a % b, and a = a / b.
- * The 32-bit code is LOV-specific due to knowing about stripe limits in
- * order to reduce the divisor to a 32-bit number. If the divisor is
- * already a 32-bit value the compiler handles this directly. */
-#if BITS_PER_LONG > 32
-# define lov_do_div64(n,base) ({ \
- uint64_t __base = (base); \
- uint64_t __rem; \
- __rem = ((uint64_t)(n)) % __base; \
- (n) = ((uint64_t)(n)) / __base; \
- __rem; \
- })
-#else
-# define lov_do_div64(n,base) ({ \
- uint64_t __rem; \
- if ((sizeof(base) > 4) && (((base) & 0xffffffff00000000ULL) != 0)) { \
- int __remainder; \
- LASSERTF(!((base) & (LOV_MIN_STRIPE_SIZE - 1)), "64 bit lov " \
- "division %llu / %llu\n", (n), (uint64_t)(base)); \
- __remainder = (n) & (LOV_MIN_STRIPE_SIZE - 1); \
- (n) >>= LOV_MIN_STRIPE_BITS; \
- __rem = do_div(n, (base) >> LOV_MIN_STRIPE_BITS); \
- __rem <<= LOV_MIN_STRIPE_BITS; \
- __rem += __remainder; \
- } else { \
- __rem = do_div(n, base); \
- } \
- __rem; \
- })
-#endif
-
-#define IOC_LOV_TYPE 'g'
-#define IOC_LOV_MIN_NR 50
-#define IOC_LOV_SET_OSC_ACTIVE _IOWR('g', 50, long)
-#define IOC_LOV_MAX_NR 50
-
-#define QOS_DEFAULT_THRESHOLD 10 /* MB */
-#define QOS_DEFAULT_MAXAGE 5 /* Seconds */
-
-#endif
#define OBD_ALLOC_GFP(ptr, size, gfp_mask) \
__OBD_MALLOC_VERBOSE(ptr, NULL, 0, size, gfp_mask)
-#define OBD_ALLOC(ptr, size) OBD_ALLOC_GFP(ptr, size, __GFP_IO)
-#define OBD_ALLOC_WAIT(ptr, size) OBD_ALLOC_GFP(ptr, size, GFP_IOFS)
+#define OBD_ALLOC(ptr, size) OBD_ALLOC_GFP(ptr, size, GFP_NOFS)
+#define OBD_ALLOC_WAIT(ptr, size) OBD_ALLOC_GFP(ptr, size, GFP_KERNEL)
#define OBD_ALLOC_PTR(ptr) OBD_ALLOC(ptr, sizeof(*(ptr)))
#define OBD_ALLOC_PTR_WAIT(ptr) OBD_ALLOC_WAIT(ptr, sizeof(*(ptr)))
__OBD_MALLOC_VERBOSE(ptr, cptab, cpt, size, gfp_mask)
#define OBD_CPT_ALLOC(ptr, cptab, cpt, size) \
- OBD_CPT_ALLOC_GFP(ptr, cptab, cpt, size, __GFP_IO)
+ OBD_CPT_ALLOC_GFP(ptr, cptab, cpt, size, GFP_NOFS)
#define OBD_CPT_ALLOC_PTR(ptr, cptab, cpt) \
OBD_CPT_ALLOC(ptr, cptab, cpt, sizeof(*(ptr)))
} while(0)
#define OBD_SLAB_ALLOC(ptr, slab, size) \
- OBD_SLAB_ALLOC_GFP(ptr, slab, size, __GFP_IO)
+ OBD_SLAB_ALLOC_GFP(ptr, slab, size, GFP_NOFS)
#define OBD_SLAB_CPT_ALLOC(ptr, slab, cptab, cpt, size) \
- OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, size, __GFP_IO)
+ OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, size, GFP_NOFS)
#define OBD_SLAB_ALLOC_PTR(ptr, slab) \
OBD_SLAB_ALLOC(ptr, slab, sizeof(*(ptr)))
#include "../llite/llite_internal.h"
-const struct cl_req_operations ccc_req_ops;
+static const struct cl_req_operations ccc_req_ops;
/*
* ccc_ prefix stands for "Common Client Code".
*
*/
-void *ccc_key_init(const struct lu_context *ctx,
- struct lu_context_key *key)
+void *ccc_key_init(const struct lu_context *ctx, struct lu_context_key *key)
{
struct ccc_thread_info *info;
- OBD_SLAB_ALLOC_PTR_GFP(info, ccc_thread_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(info, ccc_thread_kmem, GFP_NOFS);
if (info == NULL)
info = ERR_PTR(-ENOMEM);
return info;
{
struct ccc_session *session;
- OBD_SLAB_ALLOC_PTR_GFP(session, ccc_session_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(session, ccc_session_kmem, GFP_NOFS);
if (session == NULL)
session = ERR_PTR(-ENOMEM);
return session;
struct ccc_req *vrq;
int result;
- OBD_SLAB_ALLOC_PTR_GFP(vrq, ccc_req_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(vrq, ccc_req_kmem, GFP_NOFS);
if (vrq != NULL) {
cl_req_slice_add(req, &vrq->crq_cl, dev, &ccc_req_ops);
result = 0;
struct ccc_object *vob;
struct lu_object *obj;
- OBD_SLAB_ALLOC_PTR_GFP(vob, ccc_object_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(vob, ccc_object_kmem, GFP_NOFS);
if (vob != NULL) {
struct cl_object_header *hdr;
CLOBINVRNT(env, obj, ccc_object_invariant(obj));
- OBD_SLAB_ALLOC_PTR_GFP(clk, ccc_lock_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(clk, ccc_lock_kmem, GFP_NOFS);
if (clk != NULL) {
cl_lock_slice_add(lock, &clk->clk_cl, obj, lkops);
result = 0;
JOBSTATS_JOBID_SIZE);
}
-const struct cl_req_operations ccc_req_ops = {
+static const struct cl_req_operations ccc_req_ops = {
.cro_attr_set = ccc_req_attr_set,
.cro_completion = ccc_req_completion
};
__u32 valsize = sizeof(struct lov_desc);
int rc, easize, def_easize, cookiesize;
struct lov_desc desc;
- __u16 stripes;
+ __u16 stripes, def_stripes;
rc = obd_get_info(NULL, dt_exp, sizeof(KEY_LOVDESC), KEY_LOVDESC,
&valsize, &desc, NULL);
lsm.lsm_stripe_count = stripes;
easize = obd_size_diskmd(dt_exp, &lsm);
- lsm.lsm_stripe_count = desc.ld_default_stripe_count;
+ def_stripes = min_t(__u32, desc.ld_default_stripe_count,
+ LOV_MAX_STRIPE_COUNT);
+ lsm.lsm_stripe_count = def_stripes;
def_easize = obd_size_diskmd(dt_exp, &lsm);
cookiesize = stripes * sizeof(struct llog_cookie);
- CDEBUG(D_HA, "updating max_mdsize/max_cookiesize: %d/%d\n",
- easize, cookiesize);
+ /* default cookiesize is 0 because from 2.4 server doesn't send
+ * llog cookies to client. */
+ CDEBUG(D_HA,
+ "updating def/max_easize: %d/%d def/max_cookiesize: 0/%d\n",
+ def_easize, easize, cookiesize);
- rc = md_init_ea_size(md_exp, easize, def_easize, cookiesize);
+ rc = md_init_ea_size(md_exp, easize, def_easize, cookiesize, 0);
return rc;
}
struct ldlm_interval *node;
LASSERT(lock->l_resource->lr_type == LDLM_EXTENT);
- OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, GFP_NOFS);
if (node == NULL)
return NULL;
struct __##var##__dummy_read {;} /* semicolon catcher */
#define LDLM_POOL_PROC_WRITER(var, type) \
- int lprocfs_wr_##var(struct file *file, const char *buffer, \
+ static int lprocfs_wr_##var(struct file *file, const char *buffer, \
unsigned long count, void *data) \
{ \
struct ldlm_pool *pl = data; \
}
init_rwsem(&cli->cl_sem);
- sema_init(&cli->cl_mgc_sem, 1);
+ mutex_init(&cli->cl_mgc_mutex);
cli->cl_conn_count = 0;
memcpy(server_uuid.uuid, lustre_cfg_buf(lcfg, 2),
min_t(unsigned int, LUSTRE_CFG_BUFLEN(lcfg, 2),
LASSERT (imp->imp_state == LUSTRE_IMP_DISCON);
GOTO(out_ldlm, rc);
}
- LASSERT((*exp)->exp_connection);
+ LASSERT(*exp != NULL && (*exp)->exp_connection);
if (data) {
LASSERTF((ocd->ocd_connect_flags & data->ocd_connect_flags) ==
LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
list_del_init(&lock->l_lru);
- if (lock->l_flags & LDLM_FL_SKIPPED)
- lock->l_flags &= ~LDLM_FL_SKIPPED;
LASSERT(ns->ns_nr_unused > 0);
ns->ns_nr_unused--;
rc = 1;
LASSERT(list_empty(&lock->l_lru));
LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
list_add_tail(&lock->l_lru, &ns->ns_unused_list);
+ if (lock->l_flags & LDLM_FL_SKIPPED)
+ lock->l_flags &= ~LDLM_FL_SKIPPED;
LASSERT(ns->ns_nr_unused >= 0);
ns->ns_nr_unused++;
}
if (resource == NULL)
LBUG();
- OBD_SLAB_ALLOC_PTR_GFP(lock, ldlm_lock_slab, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(lock, ldlm_lock_slab, GFP_NOFS);
if (lock == NULL)
return NULL;
* have to allocate the interval node early otherwise we can't regrant
* this lock in the future. - jay */
if (!local && (*flags & LDLM_FL_REPLAY) && res->lr_type == LDLM_EXTENT)
- OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, GFP_NOFS);
lock_res_and_lock(lock);
if (local && lock->l_req_mode == lock->l_granted_mode) {
/* I can't check the type of lock here because the bitlock of lock
* is not held here, so do the allocation blindly. -jay */
- OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, GFP_NOFS);
if (node == NULL)
/* Actually, this causes EDEADLOCK to be returned */
return NULL;
* locks smaller in next 10h.
*/
static int ldlm_srv_pool_shrink(struct ldlm_pool *pl,
- int nr, unsigned int gfp_mask)
+ int nr, gfp_t gfp_mask)
{
__u32 limit;
* passed \a pl according to \a nr and \a gfp_mask.
*/
static int ldlm_cli_pool_shrink(struct ldlm_pool *pl,
- int nr, unsigned int gfp_mask)
+ int nr, gfp_t gfp_mask)
{
struct ldlm_namespace *ns;
int unused;
return ldlm_cancel_lru(ns, nr, LCF_ASYNC, LDLM_CANCEL_SHRINK);
}
-struct ldlm_pool_ops ldlm_srv_pool_ops = {
+static const struct ldlm_pool_ops ldlm_srv_pool_ops = {
.po_recalc = ldlm_srv_pool_recalc,
.po_shrink = ldlm_srv_pool_shrink,
.po_setup = ldlm_srv_pool_setup
};
-struct ldlm_pool_ops ldlm_cli_pool_ops = {
+static const struct ldlm_pool_ops ldlm_cli_pool_ops = {
.po_recalc = ldlm_cli_pool_recalc,
.po_shrink = ldlm_cli_pool_shrink
};
* freeable locks. Otherwise, return the number of canceled locks.
*/
int ldlm_pool_shrink(struct ldlm_pool *pl, int nr,
- unsigned int gfp_mask)
+ gfp_t gfp_mask)
{
int cancel = 0;
snprintf(var_name, MAX_STRING_SIZE, #name); \
pool_vars[0].data = var; \
pool_vars[0].fops = ops; \
- lprocfs_add_vars(pl->pl_proc_dir, pool_vars, 0);\
+ lprocfs_add_vars(pl->pl_proc_dir, pool_vars, NULL);\
} while (0)
static int ldlm_pool_proc_init(struct ldlm_pool *pl)
* count locks from all namespaces (if possible). Returns number of
* cached locks.
*/
-static unsigned long ldlm_pools_count(ldlm_side_t client, unsigned int gfp_mask)
+static unsigned long ldlm_pools_count(ldlm_side_t client, gfp_t gfp_mask)
{
int total = 0, nr_ns;
struct ldlm_namespace *ns;
return total;
}
-static unsigned long ldlm_pools_scan(ldlm_side_t client, int nr, unsigned int gfp_mask)
+static unsigned long ldlm_pools_scan(ldlm_side_t client, int nr, gfp_t gfp_mask)
{
unsigned long freed = 0;
int tmp, nr_ns;
struct ldlm_resource *res;
int idx;
- OBD_SLAB_ALLOC_PTR_GFP(res, ldlm_resource_slab, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(res, ldlm_resource_slab, GFP_NOFS);
if (res == NULL)
return NULL;
}
EXPORT_SYMBOL(cfs_cpt_table_free);
+#ifdef CONFIG_SMP
+int
+cfs_cpt_table_print(struct cfs_cpt_table *cptab, char *buf, int len)
+{
+ int rc = 0;
+
+ rc = snprintf(buf, len, "%d\t: %d\n", 0, 0);
+ len -= rc;
+ if (len <= 0)
+ return -EFBIG;
+
+ return rc;
+}
+EXPORT_SYMBOL(cfs_cpt_table_print);
+#endif /* CONFIG_SMP */
+
int
cfs_cpt_number(struct cfs_cpt_table *cptab)
{
}
EXPORT_SYMBOL(cfs_cpt_spread_node);
+int
+cfs_cpu_ht_nsiblings(int cpu)
+{
+ return 1;
+}
+EXPORT_SYMBOL(cfs_cpu_ht_nsiblings);
+
int
cfs_cpt_current(struct cfs_cpt_table *cptab, int remap)
{
/* reserved for hotplug */
unsigned long cpt_version;
/* mutex to protect cpt_cpumask */
- struct semaphore cpt_mutex;
+ struct mutex cpt_mutex;
/* scratch buffer for set/unset_node */
cpumask_t *cpt_cpumask;
};
return 0;
}
- down(&cpt_data.cpt_mutex);
+ mutex_lock(&cpt_data.cpt_mutex);
mask = cpt_data.cpt_cpumask;
cfs_node_to_cpumask(node, mask);
rc = cfs_cpt_set_cpumask(cptab, cpt, mask);
- up(&cpt_data.cpt_mutex);
+ mutex_unlock(&cpt_data.cpt_mutex);
return rc;
}
return;
}
- down(&cpt_data.cpt_mutex);
+ mutex_lock(&cpt_data.cpt_mutex);
mask = cpt_data.cpt_cpumask;
cfs_node_to_cpumask(node, mask);
cfs_cpt_unset_cpumask(cptab, cpt, mask);
- up(&cpt_data.cpt_mutex);
+ mutex_unlock(&cpt_data.cpt_mutex);
}
EXPORT_SYMBOL(cfs_cpt_unset_node);
break;
}
- if (sscanf(str, "%u%n", &cpt, &n) < 1) {
+ if (sscanf(str, "%d%n", &cpt, &n) < 1) {
CERROR("Invalid cpu pattern %s\n", str);
goto failed;
}
break;
}
- down(&cpt_data.cpt_mutex);
+ mutex_lock(&cpt_data.cpt_mutex);
/* if all HTs in a core are offline, it may break affinity */
cfs_cpu_ht_siblings(cpu, cpt_data.cpt_cpumask);
warn = any_online_cpu(*cpt_data.cpt_cpumask) >= nr_cpu_ids;
- up(&cpt_data.cpt_mutex);
+ mutex_unlock(&cpt_data.cpt_mutex);
CDEBUG(warn ? D_WARNING : D_INFO,
"Lustre: can't support CPU plug-out well now, "
"performance and stability could be impacted "
}
spin_lock_init(&cpt_data.cpt_lock);
- sema_init(&cpt_data.cpt_mutex, 1);
+ mutex_init(&cpt_data.cpt_mutex);
#ifdef CONFIG_HOTPLUG_CPU
register_hotcpu_notifier(&cfs_cpu_notifier);
return cap;
}
-static int cfs_access_process_vm(struct task_struct *tsk, unsigned long addr,
- void *buf, int len, int write)
-{
- /* Just copied from kernel for the kernels which doesn't
- * have access_process_vm() exported */
- struct mm_struct *mm;
- struct vm_area_struct *vma;
- struct page *page;
- void *old_buf = buf;
-
- mm = get_task_mm(tsk);
- if (!mm)
- return 0;
-
- down_read(&mm->mmap_sem);
- /* ignore errors, just check how much was successfully transferred */
- while (len) {
- int bytes, rc, offset;
- void *maddr;
-
- rc = get_user_pages(tsk, mm, addr, 1,
- write, 1, &page, &vma);
- if (rc <= 0)
- break;
-
- bytes = len;
- offset = addr & (PAGE_SIZE-1);
- if (bytes > PAGE_SIZE-offset)
- bytes = PAGE_SIZE-offset;
-
- maddr = kmap(page);
- if (write) {
- copy_to_user_page(vma, page, addr,
- maddr + offset, buf, bytes);
- set_page_dirty_lock(page);
- } else {
- copy_from_user_page(vma, page, addr,
- buf, maddr + offset, bytes);
- }
- kunmap(page);
- page_cache_release(page);
- len -= bytes;
- buf += bytes;
- addr += bytes;
- }
- up_read(&mm->mmap_sem);
- mmput(mm);
-
- return buf - old_buf;
-}
-
-/* Read the environment variable of current process specified by @key. */
-int cfs_get_environ(const char *key, char *value, int *val_len)
-{
- struct mm_struct *mm;
- char *buffer, *tmp_buf = NULL;
- int buf_len = PAGE_CACHE_SIZE;
- int key_len = strlen(key);
- unsigned long addr;
- int rc;
-
- buffer = kmalloc(buf_len, GFP_USER);
- if (!buffer)
- return -ENOMEM;
-
- mm = get_task_mm(current);
- if (!mm) {
- kfree(buffer);
- return -EINVAL;
- }
-
- /* Avoid deadlocks on mmap_sem if called from sys_mmap_pgoff(),
- * which is already holding mmap_sem for writes. If some other
- * thread gets the write lock in the meantime, this thread will
- * block, but at least it won't deadlock on itself. LU-1735 */
- if (down_read_trylock(&mm->mmap_sem) == 0) {
- kfree(buffer);
- return -EDEADLK;
- }
- up_read(&mm->mmap_sem);
-
- addr = mm->env_start;
- while (addr < mm->env_end) {
- int this_len, retval, scan_len;
- char *env_start, *env_end;
-
- memset(buffer, 0, buf_len);
-
- this_len = min_t(int, mm->env_end - addr, buf_len);
- retval = cfs_access_process_vm(current, addr, buffer,
- this_len, 0);
- if (retval != this_len)
- break;
-
- addr += retval;
-
- /* Parse the buffer to find out the specified key/value pair.
- * The "key=value" entries are separated by '\0'. */
- env_start = buffer;
- scan_len = this_len;
- while (scan_len) {
- char *entry;
- int entry_len;
-
- env_end = memscan(env_start, '\0', scan_len);
- LASSERT(env_end >= env_start &&
- env_end <= env_start + scan_len);
-
- /* The last entry of this buffer cross the buffer
- * boundary, reread it in next cycle. */
- if (unlikely(env_end - env_start == scan_len)) {
- /* This entry is too large to fit in buffer */
- if (unlikely(scan_len == this_len)) {
- CERROR("Too long env variable.\n");
- GOTO(out, rc = -EINVAL);
- }
- addr -= scan_len;
- break;
- }
-
- entry = env_start;
- entry_len = env_end - env_start;
-
- /* Key length + length of '=' */
- if (entry_len > key_len + 1 &&
- !memcmp(entry, key, key_len)) {
- entry += key_len + 1;
- entry_len -= key_len + 1;
- /* The 'value' buffer passed in is too small.*/
- if (entry_len >= *val_len)
- GOTO(out, rc = -EOVERFLOW);
-
- memcpy(value, entry, entry_len);
- *val_len = entry_len;
- GOTO(out, rc = 0);
- }
-
- scan_len -= (env_end - env_start + 1);
- env_start = env_end + 1;
- }
- }
- GOTO(out, rc = -ENOENT);
-
-out:
- mmput(mm);
- kfree((void *)buffer);
- if (tmp_buf)
- kfree((void *)tmp_buf);
- return rc;
-}
-EXPORT_SYMBOL(cfs_get_environ);
-
EXPORT_SYMBOL(cfs_cap_raise);
EXPORT_SYMBOL(cfs_cap_lower);
EXPORT_SYMBOL(cfs_cap_raised);
{
struct libcfs_ioctl_hdr *hdr;
struct libcfs_ioctl_data *data;
+ int orig_len;
int err;
hdr = (struct libcfs_ioctl_hdr *)buf;
return -EINVAL;
}
+ orig_len = hdr->ioc_len;
err = copy_from_user(buf, (void *)arg, hdr->ioc_len);
if (err)
return err;
+ if (orig_len != data->ioc_len)
+ return -EINVAL;
if (libcfs_ioctl_is_invalid(data)) {
CERROR("PORTALS: ioctl not correctly formatted\n");
CERROR ("Can't create socket: %d\n", rc);
return rc;
}
-
- sock_filp = sock_alloc_file(sock, 0, NULL);
- if (IS_ERR(sock_filp)) {
- sock_release(sock);
- rc = PTR_ERR(sock_filp);
- goto out;
- }
-
- set_fs(KERNEL_DS);
- if (sock_filp->f_op->unlocked_ioctl)
- rc = sock_filp->f_op->unlocked_ioctl(sock_filp, cmd, arg);
- set_fs(oldmm);
-
- fput(sock_filp);
-out:
+ rc = kernel_sock_ioctl(sock, cmd, arg);
+ sock_release(sock);
return rc;
}
libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout)
{
int rc;
- mm_segment_t oldmm = get_fs();
long ticks = timeout * HZ;
unsigned long then;
struct timeval tv;
.tv_sec = ticks / HZ,
.tv_usec = ((ticks % HZ) * 1000000) / HZ
};
- set_fs(KERNEL_DS);
- rc = sock_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
+ rc = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
(char *)&tv, sizeof(tv));
- set_fs(oldmm);
if (rc != 0) {
CERROR("Can't set socket send timeout "
"%ld.%06d: %d\n",
libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout)
{
int rc;
- mm_segment_t oldmm = get_fs();
long ticks = timeout * HZ;
unsigned long then;
struct timeval tv;
.tv_sec = ticks / HZ,
.tv_usec = ((ticks % HZ) * 1000000) / HZ
};
- set_fs(KERNEL_DS);
- rc = sock_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
+ rc = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
(char *)&tv, sizeof(tv));
- set_fs(oldmm);
if (rc != 0) {
CERROR("Can't set socket recv timeout %ld.%06d: %d\n",
(long)tv.tv_sec, (int)tv.tv_usec, rc);
struct socket *sock;
int rc;
int option;
- mm_segment_t oldmm = get_fs();
/* All errors are fatal except bind failure if the port is in use */
*fatal = 1;
return (rc);
}
- set_fs (KERNEL_DS);
option = 1;
- rc = sock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ rc = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char *)&option, sizeof (option));
- set_fs (oldmm);
if (rc != 0) {
CERROR("Can't set SO_REUSEADDR for socket: %d\n", rc);
goto failed;
int
libcfs_sock_setbuf (struct socket *sock, int txbufsize, int rxbufsize)
{
- mm_segment_t oldmm = get_fs();
int option;
int rc;
if (txbufsize != 0) {
option = txbufsize;
- set_fs (KERNEL_DS);
- rc = sock_setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
+ rc = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
(char *)&option, sizeof (option));
- set_fs (oldmm);
if (rc != 0) {
CERROR ("Can't set send buffer %d: %d\n",
option, rc);
if (rxbufsize != 0) {
option = rxbufsize;
- set_fs (KERNEL_DS);
- rc = sock_setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
+ rc = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
(char *)&option, sizeof (option));
- set_fs (oldmm);
if (rc != 0) {
CERROR ("Can't set receive buffer %d: %d\n",
option, rc);
}
int
-kportal_memhog_alloc (struct libcfs_device_userstate *ldu, int npages, int flags)
+kportal_memhog_alloc(struct libcfs_device_userstate *ldu, int npages,
+ gfp_t flags)
{
struct page **level0p;
struct page **level1p;
int
libcfs_ip_str2addr(const char *str, int nob, __u32 *addr)
{
- int a;
- int b;
- int c;
- int d;
- int n = nob; /* XscanfX */
+ unsigned int a;
+ unsigned int b;
+ unsigned int c;
+ unsigned int d;
+ int n = nob; /* XscanfX */
/* numeric IP? */
if (sscanf(str, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n) >= 4 &&
{
struct netstrfns *uninitialized_var(nf);
int nob;
- int netnum;
+ unsigned int netnum;
int i;
for (i = 0; i < libcfs_nnetstrfns; i++) {
return list_entry(list, struct cfs_trace_page, linkage);
}
-static struct cfs_trace_page *cfs_tage_alloc(int gfp)
+static struct cfs_trace_page *cfs_tage_alloc(gfp_t gfp)
{
struct page *page;
struct cfs_trace_page *tage;
list_move_tail(&tage->linkage, queue);
}
-int cfs_trace_refill_stock(struct cfs_trace_cpu_data *tcd, int gfp,
+int cfs_trace_refill_stock(struct cfs_trace_cpu_data *tcd, gfp_t gfp,
struct list_head *stock)
{
int i;
cdls->cdls_delay /= libcfs_console_backoff * 4;
} else {
cdls->cdls_delay *= libcfs_console_backoff;
-
- if (cdls->cdls_delay < libcfs_console_min_delay)
- cdls->cdls_delay = libcfs_console_min_delay;
- else if (cdls->cdls_delay > libcfs_console_max_delay)
- cdls->cdls_delay = libcfs_console_max_delay;
}
+ if (cdls->cdls_delay < libcfs_console_min_delay)
+ cdls->cdls_delay = libcfs_console_min_delay;
+ else if (cdls->cdls_delay > libcfs_console_max_delay)
+ cdls->cdls_delay = libcfs_console_max_delay;
+
/* ensure cdls_next is never zero after it's been seen */
cdls->cdls_next = (cfs_time_current() + cdls->cdls_delay) | 1;
}
put_cpu();
}
-int cfs_trace_refill_stock(struct cfs_trace_cpu_data *tcd, int gfp,
+int cfs_trace_refill_stock(struct cfs_trace_cpu_data *tcd, gfp_t gfp,
struct list_head *stock);
char ws_name[CFS_WS_NAME_LEN];
} cfs_wi_sched_t;
-struct cfs_workitem_data {
+static struct cfs_workitem_data {
/** serialize */
spinlock_t wi_glock;
/** list of all schedulers */
ll_intent_release(lld->lld_it);
OBD_FREE(lld->lld_it, sizeof(*lld->lld_it));
}
- LASSERT(lld->lld_cwd_count == 0);
- LASSERT(lld->lld_mnt_count == 0);
+
de->d_fsdata = NULL;
call_rcu(&lld->lld_rcu_head, free_dentry_data);
}
* an AST before calling d_revalidate_it(). The dentry still exists (marked
* INVALID) so d_lookup() matches it, but we have no lock on it (so
* lock_match() fails) and we spin around real_lookup(). */
-int ll_dcompare(const struct dentry *parent, const struct dentry *dentry,
- unsigned int len, const char *str, const struct qstr *name)
+static int ll_dcompare(const struct dentry *parent, const struct dentry *dentry,
+ unsigned int len, const char *str,
+ const struct qstr *name)
{
if (len != name->len)
return 1;
ll_intent_drop_lock(it);
/* We are still holding extra reference on a request, need to free it */
if (it_disposition(it, DISP_ENQ_OPEN_REF))
- ptlrpc_req_finished(it->d.lustre.it_data); /* ll_file_open */
+ ptlrpc_req_finished(it->d.lustre.it_data); /* ll_file_open */
+
if (it_disposition(it, DISP_ENQ_CREATE_REF)) /* create rec */
ptlrpc_req_finished(it->d.lustre.it_data);
}
}
-void ll_frob_intent(struct lookup_intent **itp, struct lookup_intent *deft)
-{
- struct lookup_intent *it = *itp;
-
- if (!it || it->it_op == IT_GETXATTR)
- it = *itp = deft;
-
-}
-
static int ll_revalidate_dentry(struct dentry *dentry,
unsigned int lookup_flags)
{
/*
* Always trust cached dentries. Update statahead window if necessary.
*/
-int ll_revalidate_nd(struct dentry *dentry, unsigned int flags)
+static int ll_revalidate_nd(struct dentry *dentry, unsigned int flags)
{
int rc;
}
-void ll_d_iput(struct dentry *de, struct inode *inode)
+static void ll_d_iput(struct dentry *de, struct inode *inode)
{
LASSERT(inode);
if (!find_cbdata(inode))
iput(inode);
}
-struct dentry_operations ll_d_ops = {
+const struct dentry_operations ll_d_ops = {
.d_revalidate = ll_revalidate_nd,
.d_release = ll_release,
.d_delete = ll_ddelete,
return rc;
}
-int ll_send_mgc_param(struct obd_export *mgc, char *string)
+static int ll_send_mgc_param(struct obd_export *mgc, char *string)
{
struct mgs_send_param *msp;
int rc = 0;
int rc, lmmsize;
struct md_op_data *op_data;
- rc = ll_get_max_mdsize(sbi, &lmmsize);
+ rc = ll_get_default_mdsize(sbi, &lmmsize);
if (rc)
return rc;
/* Compute the whole struct size */
totalsize = hur_len(hur);
OBD_FREE_PTR(hur);
+
+ /* Final size will be more than double totalsize */
+ if (totalsize >= MDS_MAXREQSIZE / 3)
+ return -E2BIG;
+
OBD_ALLOC_LARGE(hur, totalsize);
if (hur == NULL)
return -ENOMEM;
return ret;
}
-int ll_dir_open(struct inode *inode, struct file *file)
+static int ll_dir_open(struct inode *inode, struct file *file)
{
return ll_file_open(inode, file);
}
-int ll_dir_release(struct inode *inode, struct file *file)
+static int ll_dir_release(struct inode *inode, struct file *file)
{
return ll_file_release(inode, file);
}
-struct file_operations ll_dir_operations = {
+const struct file_operations ll_dir_operations = {
.llseek = ll_dir_seek,
.open = ll_dir_open,
.release = ll_dir_release,
#include "cl_object.h"
-struct ll_file_data *ll_file_data_get(void)
+static int
+ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg);
+
+static int ll_lease_close(struct obd_client_handle *och, struct inode *inode,
+ bool *lease_broken);
+
+static enum llioc_iter
+ll_iocontrol_call(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg, int *rcp);
+
+static struct ll_file_data *ll_file_data_get(void)
{
struct ll_file_data *fd;
- OBD_SLAB_ALLOC_PTR_GFP(fd, ll_file_data_slab, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(fd, ll_file_data_slab, GFP_NOFS);
if (fd == NULL)
return NULL;
fd->fd_write_failed = false;
return rc;
}
-int ll_md_close(struct obd_export *md_exp, struct inode *inode,
- struct file *file)
+static int ll_md_close(struct obd_export *md_exp, struct inode *inode,
+ struct file *file)
{
struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
struct ll_inode_info *lli = ll_i2info(inode);
return md_set_open_replay_data(md_exp, och, it);
}
-int ll_local_open(struct file *file, struct lookup_intent *it,
- struct ll_file_data *fd, struct obd_client_handle *och)
+static int ll_local_open(struct file *file, struct lookup_intent *it,
+ struct ll_file_data *fd, struct obd_client_handle *och)
{
struct inode *inode = file->f_dentry->d_inode;
struct ll_inode_info *lli = ll_i2info(inode);
/**
* Acquire a lease and open the file.
*/
-struct obd_client_handle *ll_lease_open(struct inode *inode, struct file *file,
- fmode_t fmode, __u64 open_flags)
+static struct obd_client_handle *
+ll_lease_open(struct inode *inode, struct file *file, fmode_t fmode,
+ __u64 open_flags)
{
struct lookup_intent it = { .it_op = IT_OPEN };
struct ll_sb_info *sbi = ll_i2sbi(inode);
OBD_FREE_PTR(och);
return ERR_PTR(rc);
}
-EXPORT_SYMBOL(ll_lease_open);
/**
* Release lease and close the file.
* It will check if the lease has ever broken.
*/
-int ll_lease_close(struct obd_client_handle *och, struct inode *inode,
- bool *lease_broken)
+static int ll_lease_close(struct obd_client_handle *och, struct inode *inode,
+ bool *lease_broken)
{
struct ldlm_lock *lock;
bool cancelled = true;
NULL);
return rc;
}
-EXPORT_SYMBOL(ll_lease_close);
/* Fills the obdo with the attributes for the lsm */
static int ll_lsm_getattr(struct lov_stripe_md *lsm, struct obd_export *exp,
struct md_op_data *op_data;
int rc, lmmsize;
- rc = ll_get_max_mdsize(sbi, &lmmsize);
+ rc = ll_get_default_mdsize(sbi, &lmmsize);
if (rc)
return rc;
return rc;
}
-int ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
+static int
+ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
{
struct ll_inode_info *lli = ll_i2info(inode);
struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
* Get size for inode for which FIEMAP mapping is requested.
* Make the FIEMAP get_info call and returns the result.
*/
-int ll_do_fiemap(struct inode *inode, struct ll_user_fiemap *fiemap,
- int num_bytes)
+static int ll_do_fiemap(struct inode *inode, struct ll_user_fiemap *fiemap,
+ size_t num_bytes)
{
struct obd_export *exp = ll_i2dtexp(inode);
struct lov_stripe_md *lsm = NULL;
struct ll_fiemap_info_key fm_key = { .name = KEY_FIEMAP, };
- int vallen = num_bytes;
+ __u32 vallen = num_bytes;
int rc;
/* Checks for fiemap flags */
if (get_user(extent_count,
&((struct ll_user_fiemap __user *)arg)->fm_extent_count))
return -EFAULT;
+
+ if (extent_count >=
+ (SIZE_MAX - sizeof(*fiemap_s)) / sizeof(struct ll_fiemap_extent))
+ return -EINVAL;
num_bytes = sizeof(*fiemap_s) + (extent_count *
sizeof(struct ll_fiemap_extent));
return rc;
}
-long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long
+ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct inode *inode = file->f_dentry->d_inode;
struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
}
-loff_t ll_file_seek(struct file *file, loff_t offset, int origin)
+static loff_t ll_file_seek(struct file *file, loff_t offset, int origin)
{
struct inode *inode = file->f_dentry->d_inode;
loff_t retval, eof = 0;
return retval;
}
-int ll_flush(struct file *file, fl_owner_t id)
+static int ll_flush(struct file *file, fl_owner_t id)
{
struct inode *inode = file->f_dentry->d_inode;
struct ll_inode_info *lli = ll_i2info(inode);
/**
* Called to make sure a portion of file has been written out.
- * if @local_only is not true, it will send OST_SYNC RPCs to ost.
+ * if @mode is not CL_FSYNC_LOCAL, it will send OST_SYNC RPCs to OST.
*
* Return how many pages have been written.
*/
if (!err)
ptlrpc_req_finished(req);
- if (datasync && S_ISREG(inode->i_mode)) {
+ if (S_ISREG(inode->i_mode)) {
struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
- err = cl_sync_file_range(inode, 0, OBD_OBJECT_EOF,
- CL_FSYNC_ALL, 0);
+ err = cl_sync_file_range(inode, start, end, CL_FSYNC_ALL, 0);
if (rc == 0 && err < 0)
rc = err;
if (rc < 0)
return rc;
}
-int ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
+static int
+ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
{
struct inode *inode = file->f_dentry->d_inode;
struct ll_sb_info *sbi = ll_i2sbi(inode);
return rc;
}
-int ll_file_noflock(struct file *file, int cmd, struct file_lock *file_lock)
+static int
+ll_file_noflock(struct file *file, int cmd, struct file_lock *file_lock)
{
return -ENOSYS;
}
if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
return 0;
} else if (rc != 0) {
- CERROR("%s: revalidate FID "DFID" error: rc = %d\n",
- ll_get_fsname(inode->i_sb, NULL, 0),
- PFID(ll_inode2fid(inode)), rc);
+ CDEBUG_LIMIT((rc == -EACCES || rc == -EIDRM) ? D_INFO : D_ERROR,
+ "%s: revalidate FID "DFID" error: rc = %d\n",
+ ll_get_fsname(inode->i_sb, NULL, 0),
+ PFID(ll_inode2fid(inode)), rc);
}
return rc;
}
-int __ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it,
- __u64 ibits)
+static int __ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
{
struct inode *inode = dentry->d_inode;
struct ptlrpc_request *req = NULL;
int ealen = 0;
if (S_ISREG(inode->i_mode)) {
- rc = ll_get_max_mdsize(sbi, &ealen);
+ rc = ll_get_default_mdsize(sbi, &ealen);
if (rc)
return rc;
valid |= OBD_MD_FLEASIZE | OBD_MD_FLMODEASIZE;
return rc;
}
-int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it,
- __u64 ibits)
+static int ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
{
struct inode *inode = dentry->d_inode;
int rc;
- rc = __ll_inode_revalidate_it(dentry, it, ibits);
+ rc = __ll_inode_revalidate(dentry, ibits);
if (rc != 0)
return rc;
return rc;
}
-int ll_getattr_it(struct vfsmount *mnt, struct dentry *de,
- struct lookup_intent *it, struct kstat *stat)
+int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat)
{
struct inode *inode = de->d_inode;
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ll_inode_info *lli = ll_i2info(inode);
int res = 0;
- res = ll_inode_revalidate_it(de, it, MDS_INODELOCK_UPDATE |
- MDS_INODELOCK_LOOKUP);
+ res = ll_inode_revalidate(de, MDS_INODELOCK_UPDATE |
+ MDS_INODELOCK_LOOKUP);
ll_stats_ops_tally(sbi, LPROC_LL_GETATTR, 1);
if (res)
return 0;
}
-int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat)
-{
- struct lookup_intent it = { .it_op = IT_GETATTR };
-
- return ll_getattr_it(mnt, de, &it, stat);
-}
-int ll_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
- __u64 start, __u64 len)
+static int ll_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+ __u64 start, __u64 len)
{
int rc;
size_t num_bytes;
fiemap->fm_extent_count = fieinfo->fi_extents_max;
fiemap->fm_start = start;
fiemap->fm_length = len;
- memcpy(&fiemap->fm_extents[0], fieinfo->fi_extents_start,
- sizeof(struct ll_fiemap_extent));
+ if (extent_count > 0)
+ memcpy(&fiemap->fm_extents[0], fieinfo->fi_extents_start,
+ sizeof(struct ll_fiemap_extent));
rc = ll_do_fiemap(inode, fiemap, num_bytes);
fieinfo->fi_flags = fiemap->fm_flags;
fieinfo->fi_extents_mapped = fiemap->fm_mapped_extents;
- memcpy(fieinfo->fi_extents_start, &fiemap->fm_extents[0],
- fiemap->fm_mapped_extents * sizeof(struct ll_fiemap_extent));
+ if (extent_count > 0)
+ memcpy(fieinfo->fi_extents_start, &fiemap->fm_extents[0],
+ fiemap->fm_mapped_extents *
+ sizeof(struct ll_fiemap_extent));
OBD_FREE_LARGE(fiemap, num_bytes);
return rc;
}
-struct posix_acl * ll_get_acl(struct inode *inode, int type)
+struct posix_acl *ll_get_acl(struct inode *inode, int type)
{
struct ll_inode_info *lli = ll_i2info(inode);
struct posix_acl *acl = NULL;
* need to do it before permission check. */
if (inode == inode->i_sb->s_root->d_inode) {
- struct lookup_intent it = { .it_op = IT_LOOKUP };
-
- rc = __ll_inode_revalidate_it(inode->i_sb->s_root, &it,
- MDS_INODELOCK_LOOKUP);
+ rc = __ll_inode_revalidate(inode->i_sb->s_root,
+ MDS_INODELOCK_LOOKUP);
if (rc)
return rc;
}
EXPORT_SYMBOL(ll_iocontrol_register);
EXPORT_SYMBOL(ll_iocontrol_unregister);
-enum llioc_iter ll_iocontrol_call(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg, int *rcp)
+static enum llioc_iter
+ll_iocontrol_call(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg, int *rcp)
{
enum llioc_iter ret = LLIOC_CONT;
struct llioc_data *data;
* layout here. Please note that we can't use the LVB buffer in
* completion AST because it doesn't have a large enough buffer */
oc = ll_mdscapa_get(inode);
- rc = ll_get_max_mdsize(sbi, &lmmsize);
+ rc = ll_get_default_mdsize(sbi, &lmmsize);
if (rc == 0)
rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc,
OBD_MD_FLXATTR, XATTR_NAME_LOV, NULL, 0,
return rc;
body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
- if (body == NULL || body->eadatasize > lmmsize)
+ if (body == NULL)
GOTO(out, rc = -EPROTO);
lmmsize = body->eadatasize;
if (lvb_ready) {
/* layout_gen must be valid if layout lock is not
* cancelled and stripe has already set */
- *gen = lli->lli_layout_gen;
+ *gen = ll_layout_version_get(lli);
rc = 0;
}
GOTO(out, rc);
};
int rc;
- *gen = lli->lli_layout_gen;
- if (!(sbi->ll_flags & LL_SBI_LAYOUT_LOCK))
+ *gen = ll_layout_version_get(lli);
+ if (!(sbi->ll_flags & LL_SBI_LAYOUT_LOCK) || *gen != LL_LAYOUT_GEN_NONE)
return 0;
/* sanity checks */
LASSERT(fid_is_sane(ll_inode2fid(inode)));
LASSERT(S_ISREG(inode->i_mode));
- /* mostly layout lock is caching on the local side, so try to match
- * it before grabbing layout lock mutex. */
- mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0,
- LCK_CR | LCK_CW | LCK_PR | LCK_PW);
- if (mode != 0) { /* hit cached lock */
- rc = ll_layout_lock_set(&lockh, mode, inode, gen, false);
- if (rc == 0)
- return 0;
-
- /* better hold lli_layout_mutex to try again otherwise
- * it will have starvation problem. */
- }
-
/* take layout lock mutex to enqueue layout lock exclusively. */
mutex_lock(&lli->lli_layout_mutex);
again:
- /* try again. Maybe somebody else has done this. */
+ /* mostly layout lock is caching on the local side, so try to match
+ * it before grabbing layout lock mutex. */
mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0,
LCK_CR | LCK_CW | LCK_PR | LCK_PW);
if (mode != 0) { /* hit cached lock */
static unsigned long long ll_capa_renewal_failed = 0;
static unsigned long long ll_capa_renewal_retries = 0;
+static int ll_update_capa(struct obd_capa *ocapa, struct lustre_capa *capa);
+
static inline void update_capa_timer(struct obd_capa *ocapa, cfs_time_t expiry)
{
if (cfs_time_before(expiry, ll_capa_timer.expires) ||
oc->c_expiry = cfs_time_add(oc->c_expiry, cfs_time_seconds(delay));
}
-int ll_update_capa(struct obd_capa *ocapa, struct lustre_capa *capa)
+static int ll_update_capa(struct obd_capa *ocapa, struct lustre_capa *capa)
{
struct inode *inode = ocapa->u.cli.inode;
int rc = 0;
#define LUSTRE_FPRIVATE(file) ((file)->private_data)
struct ll_dentry_data {
- int lld_cwd_count;
- int lld_mnt_count;
- struct obd_client_handle lld_cwd_och;
- struct obd_client_handle lld_mnt_och;
struct lookup_intent *lld_it;
unsigned int lld_sa_generation;
unsigned int lld_invalid:1;
#define ll_d2d(de) ((struct ll_dentry_data*)((de)->d_fsdata))
-extern struct file_operations ll_pgcache_seq_fops;
-
#define LLI_INODE_MAGIC 0x111d0de5
#define LLI_INODE_DEAD 0xdeadd00d
/* Sizeon-on-MDS attributes are changed. An attribute update needs to
* be sent to MDS. */
LLIF_SOM_DIRTY = (1 << 3),
- /* File is contented */
- LLIF_CONTENDED = (1 << 4),
- /* Truncate uses server lock for this file */
- LLIF_SRVLOCK = (1 << 5),
/* File data is modified. */
- LLIF_DATA_MODIFIED = (1 << 6),
+ LLIF_DATA_MODIFIED = (1 << 4),
/* File is being restored */
- LLIF_FILE_RESTORING = (1 << 7),
+ LLIF_FILE_RESTORING = (1 << 5),
/* Xattr cache is attached to the file */
- LLIF_XATTR_CACHE = (1 << 8),
+ LLIF_XATTR_CACHE = (1 << 6),
};
struct ll_inode_info {
* cleanup the dir readahead. */
void *d_opendir_key;
struct ll_statahead_info *d_sai;
- struct posix_acl *d_def_acl;
/* protect statahead stuff. */
spinlock_t d_sa_lock;
/* "opendir_pid" is the token when lookup/revalid
#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_def_acl u.d.d_def_acl
#define lli_sa_lock u.d.d_sa_lock
#define lli_opendir_pid u.d.d_opendir_pid
/* for non-directory */
struct {
- struct semaphore f_size_sem;
- void *f_size_sem_owner;
+ struct mutex f_size_mutex;
char *f_symlink_name;
__u64 f_maxbytes;
/*
/* for writepage() only to communicate to fsync */
int f_async_rc;
- /* volatile file criteria is based on file name, this
- * flag is used to keep the test result, so the strcmp
- * is done only once
- */
- bool f_volatile;
/*
* whenever a process try to read/write the file, the
* jobid of the process will be saved here, and it'll
char f_jobid[JOBSTATS_JOBID_SIZE];
} f;
-#define lli_size_sem u.f.f_size_sem
-#define lli_size_sem_owner u.f.f_size_sem_owner
+#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_agl_index u.f.f_agl_index
#define lli_async_rc u.f.f_async_rc
#define lli_jobid u.f.f_jobid
-#define lli_volatile u.f.f_volatile
} u;
/* mutex to request for layout lock exclusively. */
struct mutex lli_layout_mutex;
- /* valid only inside LAYOUT ibits lock, protected by lli_layout_mutex */
+ /* Layout version, protected by lli_layout_lock */
__u32 lli_layout_gen;
+ spinlock_t lli_layout_lock;
struct rw_semaphore lli_xattrs_list_rwsem;
struct mutex lli_xattrs_enq_lock;
struct list_head lli_xattrs;/* ll_xattr_entry->xe_list */
};
+static inline __u32 ll_layout_version_get(struct ll_inode_info *lli)
+{
+ __u32 gen;
+
+ spin_lock(&lli->lli_layout_lock);
+ gen = lli->lli_layout_gen;
+ spin_unlock(&lli->lli_layout_lock);
+
+ return gen;
+}
+
+static inline void ll_layout_version_set(struct ll_inode_info *lli, __u32 gen)
+{
+ spin_lock(&lli->lli_layout_lock);
+ lli->lli_layout_gen = gen;
+ spin_unlock(&lli->lli_layout_lock);
+}
+
int ll_xattr_cache_destroy(struct inode *inode);
int ll_xattr_cache_get(struct inode *inode,
* Locking to guarantee consistency of non-atomic updates to long long i_size,
* consistency between file size and KMS.
*
- * Implemented by ->lli_size_sem and ->lsm_lock, nested in that order.
+ * Implemented by ->lli_size_mutex and ->lsm_lock, nested in that order.
*/
void ll_inode_size_lock(struct inode *inode);
"xattr", \
}
-/* default value for ll_sb_info->contention_time */
-#define SBI_DEFAULT_CONTENTION_SECONDS 60
-/* default value for lockless_truncate_enable */
-#define SBI_DEFAULT_LOCKLESS_TRUNCATE_ENABLE 1
#define RCE_HASHES 32
struct rmtacl_ctl_entry {
return &lli->lli_vfs_inode;
}
-struct it_cb_data {
- struct inode *icbd_parent;
- struct dentry **icbd_childp;
- obd_id hash;
-};
-
__u32 ll_i2suppgid(struct inode *i);
void ll_i2gids(__u32 *suppgids, struct inode *i1,struct inode *i2);
{
#if BITS_PER_LONG == 32
return 1;
+#elif defined(CONFIG_COMPAT)
+ return unlikely(is_compat_task() || (sbi->ll_flags & LL_SBI_32BIT_API));
#else
- return unlikely(
-#ifdef CONFIG_COMPAT
- is_compat_task() ||
-#endif
- (sbi->ll_flags & LL_SBI_32BIT_API)
- );
+ return unlikely(sbi->ll_flags & LL_SBI_32BIT_API);
#endif
}
-#define LLAP_MAGIC 98764321
-
-extern struct kmem_cache *ll_async_page_slab;
-extern size_t ll_async_page_slab_size;
-
void ll_ra_read_in(struct file *f, struct ll_ra_read *rar);
void ll_ra_read_ex(struct file *f, struct ll_ra_read *rar);
struct ll_ra_read *ll_ra_read_get(struct file *f);
/* llite/dir.c */
void ll_release_page(struct page *page, int remove);
-extern struct file_operations ll_dir_operations;
-extern struct inode_operations ll_dir_inode_operations;
+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_get_mdt_idx(struct inode *inode);
/* 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,
int ll_commit_write(struct file *, struct page *, unsigned from, unsigned to);
int ll_writepage(struct page *page, struct writeback_control *wbc);
int ll_writepages(struct address_space *, struct writeback_control *wbc);
-void ll_removepage(struct page *page);
int ll_readpage(struct file *file, struct page *page);
void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras);
-int ll_file_punch(struct inode *, loff_t, int);
-ssize_t ll_file_lockless_io(struct file *, char *, size_t, loff_t *, int);
-void ll_clear_file_contended(struct inode*);
-int ll_sync_page_range(struct inode *, struct address_space *, loff_t, size_t);
int ll_readahead(const struct lu_env *env, struct cl_io *io,
struct ll_readahead_state *ras, struct address_space *mapping,
struct cl_page_list *queue, int flags);
+#ifndef MS_HAS_NEW_AOPS
+extern const struct address_space_operations ll_aops;
+#else
+extern const struct address_space_operations_ext ll_aops;
+#endif
+
/* llite/file.c */
extern struct file_operations ll_file_operations;
extern struct file_operations ll_file_operations_flock;
extern struct file_operations ll_file_operations_noflock;
extern struct inode_operations ll_file_inode_operations;
-extern int ll_inode_revalidate_it(struct dentry *, struct lookup_intent *,
- __u64);
extern int ll_have_md_lock(struct inode *inode, __u64 *bits,
ldlm_mode_t l_req_mode);
extern ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits,
struct lustre_handle *lockh, __u64 flags,
ldlm_mode_t mode);
-int __ll_inode_revalidate_it(struct dentry *, struct lookup_intent *,
- __u64 bits);
-int ll_revalidate_nd(struct dentry *dentry, unsigned int flags);
int ll_file_open(struct inode *inode, struct file *file);
int ll_file_release(struct inode *inode, struct file *file);
int ll_glimpse_ioctl(struct ll_sb_info *sbi,
struct lov_stripe_md *lsm, lstat_t *st);
void ll_ioepoch_open(struct ll_inode_info *lli, __u64 ioepoch);
-int ll_local_open(struct file *file,
- struct lookup_intent *it, struct ll_file_data *fd,
- struct obd_client_handle *och);
int ll_release_openhandle(struct dentry *, struct lookup_intent *);
-int ll_md_close(struct obd_export *md_exp, struct inode *inode,
- struct file *file);
int ll_md_real_close(struct inode *inode, fmode_t fmode);
void ll_ioepoch_close(struct inode *inode, struct md_op_data *op_data,
struct obd_client_handle **och, unsigned long flags);
int ll_som_update(struct inode *inode, struct md_op_data *op_data);
int ll_inode_getattr(struct inode *inode, struct obdo *obdo,
__u64 ioepoch, int sync);
-int ll_md_setattr(struct dentry *dentry, struct md_op_data *op_data,
- struct md_open_data **mod);
void ll_pack_inode2opdata(struct inode *inode, struct md_op_data *op_data,
struct lustre_handle *fh);
-int ll_getattr_it(struct vfsmount *mnt, struct dentry *de,
- struct lookup_intent *it, struct kstat *stat);
int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat);
-struct ll_file_data *ll_file_data_get(void);
-struct posix_acl * ll_get_acl(struct inode *inode, int type);
+struct posix_acl *ll_get_acl(struct inode *inode, int type);
int ll_inode_permission(struct inode *inode, int mask);
int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
int *lmm_size, struct ptlrpc_request **request);
int ll_fsync(struct file *file, loff_t start, loff_t end, int data);
-int ll_do_fiemap(struct inode *inode, struct ll_user_fiemap *fiemap,
- int num_bytes);
int ll_merge_lvb(const struct lu_env *env, struct inode *inode);
-int ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg);
-int ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg);
int ll_fid2path(struct inode *inode, void *arg);
int ll_data_version(struct inode *inode, __u64 *data_version, int extent_lock);
int ll_hsm_release(struct inode *inode);
-struct obd_client_handle *ll_lease_open(struct inode *inode, struct file *file,
- fmode_t mode, __u64 flags);
-int ll_lease_close(struct obd_client_handle *och, struct inode *inode,
- bool *lease_broken);
-
/* llite/dcache.c */
int ll_d_init(struct dentry *de);
-extern struct dentry_operations ll_d_ops;
+extern const struct dentry_operations ll_d_ops;
void ll_intent_drop_lock(struct lookup_intent *);
void ll_intent_release(struct lookup_intent *);
void ll_invalidate_aliases(struct inode *);
-void ll_frob_intent(struct lookup_intent **itp, struct lookup_intent *deft);
void ll_lookup_finish_locks(struct lookup_intent *it, struct dentry *dentry);
-int ll_dcompare(const struct dentry *parent, const struct dentry *dentry,
- unsigned int len, const char *str, const struct qstr *d_name);
int ll_revalidate_it_finish(struct ptlrpc_request *request,
struct lookup_intent *it, struct dentry *de);
/* llite/llite_lib.c */
extern struct super_operations lustre_super_operations;
-char *ll_read_opt(const char *opt, char *data);
void ll_lli_init(struct ll_inode_info *lli);
int ll_fill_super(struct super_block *sb, struct vfsmount *mnt);
void ll_put_super(struct super_block *sb);
void ll_kill_super(struct super_block *sb);
struct inode *ll_inode_from_resource_lock(struct ldlm_lock *lock);
-struct inode *ll_inode_from_lock(struct ldlm_lock *lock);
void ll_clear_inode(struct inode *inode);
int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import);
int ll_setattr(struct dentry *de, struct iattr *attr);
int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
struct super_block *, struct lookup_intent *);
void lustre_dump_dentry(struct dentry *, int recur);
-void lustre_dump_inode(struct inode *);
int ll_obd_statfs(struct inode *inode, void *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_get_max_cookiesize(struct ll_sb_info *sbi, int *max_cookiesize);
+int ll_get_default_cookiesize(struct ll_sb_info *sbi, int *default_cookiesize);
int ll_process_config(struct lustre_cfg *lcfg);
struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
struct inode *i1, struct inode *i2,
struct inode *search_inode_for_lustre(struct super_block *sb,
const struct lu_fid *fid);
-/* llite/special.c */
-extern struct inode_operations ll_special_inode_operations;
-extern struct file_operations ll_special_chr_inode_fops;
-extern struct file_operations ll_special_chr_file_fops;
-extern struct file_operations ll_special_blk_inode_fops;
-extern struct file_operations ll_special_fifo_inode_fops;
-extern struct file_operations ll_special_fifo_file_fops;
-extern struct file_operations ll_special_sock_inode_fops;
-
/* llite/symlink.c */
extern struct inode_operations ll_fast_symlink_inode_operations;
* Set when cui_bead has been initialized.
*/
int cui_ra_window_set;
- /**
- * Partially truncated page, that vvp_io_trunc_start() keeps locked
- * across truncate.
- */
- struct cl_page *cui_partpage;
};
/**
struct cl_page *lcc_page;
struct lu_env *lcc_env;
int lcc_refcheck;
- int lcc_created;
};
struct vvp_thread_info {
- struct ost_lvb vti_lvb;
- struct cl_2queue vti_queue;
struct iovec vti_local_iov;
struct vvp_io_args vti_args;
struct ra_io_arg vti_ria;
return &vvp_env_session(env)->vs_ios;
}
+int vvp_global_init(void);
+void vvp_global_fini(void);
+
void ll_queue_done_writing(struct inode *inode, unsigned long flags);
void ll_close_thread_shutdown(struct ll_close_queue *lcq);
int ll_close_thread_start(struct ll_close_queue **lcq_ret);
/* llite/llite_mmap.c */
-typedef struct rb_root rb_root_t;
-typedef struct rb_node rb_node_t;
-
-struct ll_lock_tree_node;
-struct ll_lock_tree {
- rb_root_t lt_root;
- struct list_head lt_locked_list;
- struct ll_file_data *lt_fd;
-};
int ll_teardown_mmaps(struct address_space *mapping, __u64 first, __u64 last);
int ll_file_mmap(struct file * file, struct vm_area_struct * vma);
-struct ll_lock_tree_node * ll_node_from_inode(struct inode *inode, __u64 start,
- __u64 end, ldlm_mode_t mode);
void policy_from_vma(ldlm_policy_data_t *policy,
struct vm_area_struct *vma, unsigned long addr, size_t count);
struct vm_area_struct *our_vma(struct mm_struct *mm, unsigned long addr,
return fid;
}
-static inline int ll_mds_max_easize(struct super_block *sb)
-{
- return sbi2mdc(ll_s2sbi(sb))->cl_max_mds_easize;
-}
-
static inline __u64 ll_file_maxbytes(struct inode *inode)
{
return ll_i2info(inode)->lli_maxbytes;
extern struct kmem_cache *ll_remote_perm_cachep;
extern struct kmem_cache *ll_rmtperm_hash_cachep;
-struct hlist_head *alloc_rmtperm_hash(void);
void free_rmtperm_hash(struct hlist_head *hash);
int ll_update_remote_perm(struct inode *inode, struct mdt_remote_perm *perm);
int lustre_check_remote_perm(struct inode *inode, int mask);
void ll_capa_timer_callback(unsigned long unused);
struct obd_capa *ll_add_capa(struct inode *inode, struct obd_capa *ocapa);
-int ll_update_capa(struct obd_capa *ocapa, struct lustre_capa *capa);
void ll_capa_open(struct inode *inode);
void ll_capa_close(struct inode *inode);
*/
int cl_sb_init(struct super_block *sb);
int cl_sb_fini(struct super_block *sb);
-enum cl_lock_mode vvp_mode_from_vma(struct vm_area_struct *vma);
void ll_io_init(struct cl_io *io, const struct file *file, int write);
void ras_update(struct ll_sb_info *sbi, struct inode *inode,
struct ll_readahead_state *ras, unsigned long index,
unsigned hit);
void ll_ra_count_put(struct ll_sb_info *sbi, unsigned long len);
-int ll_is_file_contended(struct file *file);
void ll_ra_stats_inc(struct address_space *mapping, enum ra_stat which);
/* llite/llite_rmtacl.c */
unsigned int sai_skip_hidden;/* skipped hidden dentry count */
unsigned int sai_ls_all:1, /* "ls -al", do stat-ahead for
* hidden entries */
- sai_in_readpage:1,/* statahead is in readdir()*/
sai_agl_valid:1;/* AGL is valid for the dir */
wait_queue_head_t sai_waitq; /* stat-ahead wait queue */
struct ptlrpc_thread sai_thread; /* stat-ahead thread */
struct file *file, unsigned int cmd, unsigned long arg,
void *magic, int *rcp);
-enum llioc_iter ll_iocontrol_call(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg, int *rcp);
-
/* export functions */
/* Register ioctl block dynamatically for a regular file.
*
static inline void cl_isize_write_nolock(struct inode *inode, loff_t kms)
{
- LASSERT(down_trylock(&ll_i2info(inode)->lli_size_sem) != 0);
+ LASSERT(mutex_is_locked(&ll_i2info(inode)->lli_size_mutex));
i_size_write(inode, kms);
}
struct kmem_cache *ll_file_data_slab;
struct proc_dir_entry *proc_lustre_fs_root;
-LIST_HEAD(ll_super_blocks);
-DEFINE_SPINLOCK(ll_sb_lock);
-
-#ifndef MS_HAS_NEW_AOPS
-extern struct address_space_operations ll_aops;
-#else
-extern struct address_space_operations_ext ll_aops;
-#endif
+static LIST_HEAD(ll_super_blocks);
+static DEFINE_SPINLOCK(ll_sb_lock);
#ifndef log2
#define log2(n) ffz(~(n))
return sbi;
}
-void ll_free_sbi(struct super_block *sb)
+static void ll_free_sbi(struct super_block *sb)
{
struct ll_sb_info *sbi = ll_s2sbi(sb);
return rc;
}
-void ll_dump_inode(struct inode *inode)
+int ll_get_default_mdsize(struct ll_sb_info *sbi, int *lmmsize)
+{
+ int size, rc;
+
+ size = sizeof(int);
+ rc = obd_get_info(NULL, sbi->ll_md_exp, sizeof(KEY_DEFAULT_EASIZE),
+ KEY_DEFAULT_EASIZE, &size, lmmsize, NULL);
+ if (rc)
+ CERROR("Get default mdsize error rc %d\n", rc);
+
+ return rc;
+}
+
+int ll_get_max_cookiesize(struct ll_sb_info *sbi, int *lmmsize)
+{
+ int size, rc;
+
+ size = sizeof(int);
+ rc = obd_get_info(NULL, sbi->ll_md_exp, sizeof(KEY_MAX_COOKIESIZE),
+ KEY_MAX_COOKIESIZE, &size, lmmsize, NULL);
+ if (rc)
+ CERROR("Get max cookiesize error rc %d\n", rc);
+
+ return rc;
+}
+
+int ll_get_default_cookiesize(struct ll_sb_info *sbi, int *lmmsize)
+{
+ int size, rc;
+
+ size = sizeof(int);
+ rc = obd_get_info(NULL, sbi->ll_md_exp, sizeof(KEY_DEFAULT_COOKIESIZE),
+ KEY_DEFAULT_COOKIESIZE, &size, lmmsize, NULL);
+ if (rc)
+ CERROR("Get default cookiesize error rc %d\n", rc);
+
+ return rc;
+}
+
+static void ll_dump_inode(struct inode *inode)
{
struct ll_d_hlist_node *tmp;
int dentry_count = 0;
}
}
-void client_common_put_super(struct super_block *sb)
+static void client_common_put_super(struct super_block *sb)
{
struct ll_sb_info *sbi = ll_s2sbi(sb);
}
}
-char *ll_read_opt(const char *opt, char *data)
-{
- char *value;
- char *retval;
-
- CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data);
- if (strncmp(opt, data, strlen(opt)))
- return NULL;
- value = strchr(data, '=');
- if (value == NULL)
- return NULL;
-
- value++;
- OBD_ALLOC(retval, strlen(value) + 1);
- if (!retval) {
- CERROR("out of memory!\n");
- return NULL;
- }
-
- memcpy(retval, value, strlen(value)+1);
- CDEBUG(D_SUPER, "Assigned option: %s, value %s\n", opt, retval);
- return retval;
-}
-
static inline int ll_set_opt(const char *opt, char *data, int fl)
{
if (strncmp(opt, data, strlen(opt)) != 0)
mutex_init(&lli->lli_och_mutex);
spin_lock_init(&lli->lli_agl_lock);
lli->lli_has_smd = false;
- lli->lli_layout_gen = LL_LAYOUT_GEN_NONE;
+ spin_lock_init(&lli->lli_layout_lock);
+ ll_layout_version_set(lli, LL_LAYOUT_GEN_NONE);
lli->lli_clob = NULL;
init_rwsem(&lli->lli_xattrs_list_rwsem);
mutex_init(&lli->lli_readdir_mutex);
lli->lli_opendir_key = NULL;
lli->lli_sai = NULL;
- lli->lli_def_acl = NULL;
spin_lock_init(&lli->lli_sa_lock);
lli->lli_opendir_pid = 0;
} else {
- sema_init(&lli->lli_size_sem, 1);
- lli->lli_size_sem_owner = NULL;
+ mutex_init(&lli->lli_size_mutex);
lli->lli_symlink_name = NULL;
init_rwsem(&lli->lli_trunc_sem);
mutex_init(&lli->lli_write_mutex);
INIT_LIST_HEAD(&lli->lli_agl_list);
lli->lli_agl_index = 0;
lli->lli_async_rc = 0;
- lli->lli_volatile = false;
}
mutex_init(&lli->lli_layout_mutex);
}
return inode;
}
-struct inode *ll_inode_from_lock(struct ldlm_lock *lock)
-{
- struct inode *inode = NULL;
- /* NOTE: we depend on atomic igrab() -bzzz */
- lock_res_and_lock(lock);
- if (lock->l_ast_data) {
- struct ll_inode_info *lli = ll_i2info(lock->l_ast_data);
- if (lli->lli_inode_magic == LLI_INODE_MAGIC) {
- inode = igrab(lock->l_ast_data);
- } else {
- inode = lock->l_ast_data;
- LDLM_DEBUG_LIMIT(inode->i_state & I_FREEING ? D_INFO :
- D_WARNING, lock, "l_ast_data %p is "
- "bogus: magic %08x", lock->l_ast_data,
- lli->lli_inode_magic);
- inode = NULL;
- }
- }
- unlock_res_and_lock(lock);
- return inode;
-}
-
void ll_clear_inode(struct inode *inode)
{
struct ll_inode_info *lli = ll_i2info(inode);
if (attr->ia_valid & ATTR_SIZE)
inode_dio_write_done(inode);
mutex_unlock(&inode->i_mutex);
- down_write(&lli->lli_trunc_sem);
}
memcpy(&op_data->op_attr, attr, sizeof(*attr));
* excessive to send mtime/atime updates to OSTs when not
* setting times to past, but it is necessary due to possible
* time de-synchronization between MDT inode and OST objects */
+ if (attr->ia_valid & ATTR_SIZE)
+ down_write(&lli->lli_trunc_sem);
rc = ll_setattr_ost(inode, attr);
+ if (attr->ia_valid & ATTR_SIZE)
+ up_write(&lli->lli_trunc_sem);
out:
if (op_data) {
if (op_data->op_ioepoch) {
ll_finish_md_op_data(op_data);
}
if (!S_ISDIR(inode->i_mode)) {
- up_write(&lli->lli_trunc_sem);
mutex_lock(&inode->i_mutex);
if ((attr->ia_valid & ATTR_SIZE) && !hsm_import)
inode_dio_wait(inode);
LASSERT(!S_ISDIR(inode->i_mode));
lli = ll_i2info(inode);
- LASSERT(lli->lli_size_sem_owner != current);
- down(&lli->lli_size_sem);
- LASSERT(lli->lli_size_sem_owner == NULL);
- lli->lli_size_sem_owner = current;
+ mutex_lock(&lli->lli_size_mutex);
}
void ll_inode_size_unlock(struct inode *inode)
struct ll_inode_info *lli;
lli = ll_i2info(inode);
- LASSERT(lli->lli_size_sem_owner == current);
- lli->lli_size_sem_owner = NULL;
- up(&lli->lli_size_sem);
+ mutex_unlock(&lli->lli_size_mutex);
}
void ll_update_inode(struct inode *inode, struct lustre_md *md)
path = ll_d_path(dentry, buf, PAGE_SIZE);
}
- CWARN("%s: dirty page discard: %s/fid: "DFID"/%s may get corrupted "
- "(rc %d)\n", ll_get_fsname(page->mapping->host->i_sb, NULL, 0),
- s2lsi(page->mapping->host->i_sb)->lsi_lmd->lmd_dev,
- PFID(&obj->cob_header.coh_lu.loh_fid),
- (path && !IS_ERR(path)) ? path : "", ioret);
+ CDEBUG(D_WARNING,
+ "%s: dirty page discard: %s/fid: "DFID"/%s may get corrupted "
+ "(rc %d)\n", ll_get_fsname(page->mapping->host->i_sb, NULL, 0),
+ s2lsi(page->mapping->host->i_sb)->lsi_lmd->lmd_dev,
+ PFID(&obj->cob_header.coh_lu.loh_fid),
+ (path && !IS_ERR(path)) ? path : "", ioret);
if (dentry != NULL)
dput(dentry);
#include "llite_internal.h"
#include <linux/lustre_compat25.h>
-struct page *ll_nopage(struct vm_area_struct *vma, unsigned long address,
- int *type);
-
-static struct vm_operations_struct ll_file_vm_ops;
+static const struct vm_operations_struct ll_file_vm_ops;
void policy_from_vma(ldlm_policy_data_t *policy,
struct vm_area_struct *vma, unsigned long addr,
* \retval EINVAL if env can't allocated
* \return other error codes from cl_io_init.
*/
-struct cl_io *ll_fault_io_init(struct vm_area_struct *vma,
- struct lu_env **env_ret,
- struct cl_env_nest *nest,
- pgoff_t index, unsigned long *ra_flags)
+static struct cl_io *
+ll_fault_io_init(struct vm_area_struct *vma, struct lu_env **env_ret,
+ struct cl_env_nest *nest, pgoff_t index,
+ unsigned long *ra_flags)
{
struct file *file = vma->vm_file;
struct inode *inode = file->f_dentry->d_inode;
LASSERT(atomic_read(&vob->cob_mmap_cnt) >= 0);
}
-
-/* return the user space pointer that maps to a file offset via a vma */
-static inline unsigned long file_to_user(struct vm_area_struct *vma, __u64 byte)
-{
- return vma->vm_start + (byte - ((__u64)vma->vm_pgoff << PAGE_CACHE_SHIFT));
-
-}
-
/* XXX put nice comment here. talk about __free_pte -> dirty pages and
* nopage's reference passing to the pte */
int ll_teardown_mmaps(struct address_space *mapping, __u64 first, __u64 last)
return rc;
}
-static struct vm_operations_struct ll_file_vm_ops = {
+static const struct vm_operations_struct ll_file_vm_ops = {
.fault = ll_fault,
.page_mkwrite = ll_page_mkwrite,
.open = ll_vm_open,
if (inode)
return inode;
- rc = ll_get_max_mdsize(sbi, &eadatalen);
+ rc = ll_get_default_mdsize(sbi, &eadatalen);
if (rc)
return ERR_PTR(rc);
CDEBUG(D_INFO, "getting parent for (%lu,"DFID")\n",
dir->i_ino, PFID(ll_inode2fid(dir)));
- rc = ll_get_max_mdsize(sbi, &lmmsize);
+ rc = ll_get_default_mdsize(sbi, &lmmsize);
if (rc != 0)
return ERR_PTR(rc);
loff_t lo_offset;
loff_t lo_sizelimit;
int lo_flags;
- int (*ioctl)(struct lloop_device *, int cmd,
- unsigned long arg);
-
struct file *lo_backing_file;
struct block_device *lo_device;
unsigned lo_blocksize;
lo->lo_device = bdev;
lo->lo_flags = lo_flags;
lo->lo_backing_file = file;
- lo->ioctl = NULL;
lo->lo_sizelimit = 0;
lo->old_gfp_mask = mapping_gfp_mask(mapping);
mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
down(&lo->lo_sem);
lo->lo_backing_file = NULL;
- lo->ioctl = NULL;
lo->lo_device = NULL;
lo->lo_offset = 0;
lo->lo_sizelimit = 0;
case LL_IOC_LLOOP_INFO: {
struct lu_fid fid;
- LASSERT(lo->lo_backing_file != NULL);
+ if (lo->lo_backing_file == NULL) {
+ err = -ENOENT;
+ break;
+ }
if (inode == NULL)
inode = lo->lo_backing_file->f_dentry->d_inode;
if (lo->lo_state == LLOOP_BOUND)
#include <obd_support.h>
#include "llite_internal.h"
+#include "vvp_internal.h"
/* /proc/lustre/llite mount point registration */
-extern struct file_operations vvp_dump_pgcache_file_ops;
-struct file_operations ll_rw_extents_stats_fops;
-struct file_operations ll_rw_extents_stats_pp_fops;
-struct file_operations ll_rw_offset_stats_fops;
+static struct file_operations ll_rw_extents_stats_fops;
+static struct file_operations ll_rw_extents_stats_pp_fops;
+static struct file_operations ll_rw_offset_stats_fops;
static int ll_blksize_seq_show(struct seq_file *m, void *v)
{
cache->ccc_lru_shrinkers);
}
-static ssize_t ll_max_cached_mb_seq_write(struct file *file, const char *buffer,
- size_t count, loff_t *off)
+static ssize_t ll_max_cached_mb_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
{
struct super_block *sb = ((struct seq_file *)file->private_data)->private;
struct ll_sb_info *sbi = ll_s2sbi(sb);
int mult, rc, pages_number;
int diff = 0;
int nrpages = 0;
+ char kernbuf[128];
+
+ if (count >= sizeof(kernbuf))
+ return -EINVAL;
+
+ if (copy_from_user(kernbuf, buffer, count))
+ return -EFAULT;
+ kernbuf[count] = 0;
mult = 1 << (20 - PAGE_CACHE_SHIFT);
- buffer = lprocfs_find_named_value(buffer, "max_cached_mb:", &count);
+ buffer += lprocfs_find_named_value(kernbuf, "max_cached_mb:", &count) -
+ kernbuf;
rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult);
if (rc)
return rc;
}
LPROC_SEQ_FOPS(ll_lazystatfs);
-static int ll_maxea_size_seq_show(struct seq_file *m, void *v)
+static int ll_max_easize_seq_show(struct seq_file *m, void *v)
{
struct super_block *sb = m->private;
struct ll_sb_info *sbi = ll_s2sbi(sb);
return seq_printf(m, "%u\n", ealen);
}
-LPROC_SEQ_FOPS_RO(ll_maxea_size);
+LPROC_SEQ_FOPS_RO(ll_max_easize);
+
+static int ll_defult_easize_seq_show(struct seq_file *m, void *v)
+{
+ struct super_block *sb = m->private;
+ struct ll_sb_info *sbi = ll_s2sbi(sb);
+ unsigned int ealen;
+ int rc;
+
+ rc = ll_get_default_mdsize(sbi, &ealen);
+ if (rc)
+ return rc;
+
+ return seq_printf(m, "%u\n", ealen);
+}
+LPROC_SEQ_FOPS_RO(ll_defult_easize);
+
+static int ll_max_cookiesize_seq_show(struct seq_file *m, void *v)
+{
+ struct super_block *sb = m->private;
+ struct ll_sb_info *sbi = ll_s2sbi(sb);
+ unsigned int cookielen;
+ int rc;
+
+ rc = ll_get_max_cookiesize(sbi, &cookielen);
+ if (rc)
+ return rc;
+
+ return seq_printf(m, "%u\n", cookielen);
+}
+LPROC_SEQ_FOPS_RO(ll_max_cookiesize);
+
+static int ll_defult_cookiesize_seq_show(struct seq_file *m, void *v)
+{
+ struct super_block *sb = m->private;
+ struct ll_sb_info *sbi = ll_s2sbi(sb);
+ unsigned int cookielen;
+ int rc;
+
+ rc = ll_get_default_cookiesize(sbi, &cookielen);
+ if (rc)
+ return rc;
+
+ return seq_printf(m, "%u\n", cookielen);
+}
+LPROC_SEQ_FOPS_RO(ll_defult_cookiesize);
static int ll_sbi_flags_seq_show(struct seq_file *m, void *v)
{
{ "statahead_agl", &ll_statahead_agl_fops, 0 },
{ "statahead_stats", &ll_statahead_stats_fops, 0, 0 },
{ "lazystatfs", &ll_lazystatfs_fops, 0 },
- { "max_easize", &ll_maxea_size_fops, 0, 0 },
+ { "max_easize", &ll_max_easize_fops, 0, 0 },
+ { "default_easize", &ll_defult_easize_fops, 0, 0 },
+ { "max_cookiesize", &ll_max_cookiesize_fops, 0, 0 },
+ { "default_cookiesize", &ll_defult_cookiesize_fops, 0, 0 },
{ "sbi_flags", &ll_sbi_flags_fops, 0, 0 },
{ "xattr_cache", &ll_xattr_cache_fops, 0, 0 },
{ 0 }
#define MAX_STRING_SIZE 128
-struct llite_file_opcode {
+static const struct llite_file_opcode {
__u32 opcode;
__u32 type;
const char *opname;
}
static ssize_t ll_rw_extents_stats_pp_seq_write(struct file *file,
- const char *buf, size_t len,
+ const char __user *buf,
+ size_t len,
loff_t *off)
{
struct seq_file *seq = file->private_data;
int i;
int value = 1, rc = 0;
+ if (len == 0)
+ return -EINVAL;
+
rc = lprocfs_write_helper(buf, len, &value);
- if (rc < 0 && (strcmp(buf, "disabled") == 0 ||
- strcmp(buf, "Disabled") == 0))
- value = 0;
+ if (rc < 0 && len < 16) {
+ char kernbuf[16];
+
+ if (copy_from_user(kernbuf, buf, len))
+ return -EFAULT;
+ kernbuf[len] = 0;
+
+ if (kernbuf[len - 1] == '\n')
+ kernbuf[len - 1] = 0;
+
+ if (strcmp(kernbuf, "disabled") == 0 ||
+ strcmp(kernbuf, "Disabled") == 0)
+ value = 0;
+ }
if (value == 0)
sbi->ll_rw_stats_on = 0;
return 0;
}
-static ssize_t ll_rw_extents_stats_seq_write(struct file *file, const char *buf,
- size_t len, loff_t *off)
+static ssize_t ll_rw_extents_stats_seq_write(struct file *file,
+ const char __user *buf,
+ size_t len, loff_t *off)
{
struct seq_file *seq = file->private_data;
struct ll_sb_info *sbi = seq->private;
int i;
int value = 1, rc = 0;
+ if (len == 0)
+ return -EINVAL;
+
rc = lprocfs_write_helper(buf, len, &value);
- if (rc < 0 && (strcmp(buf, "disabled") == 0 ||
- strcmp(buf, "Disabled") == 0))
- value = 0;
+ if (rc < 0 && len < 16) {
+ char kernbuf[16];
+
+ if (copy_from_user(kernbuf, buf, len))
+ return -EFAULT;
+ kernbuf[len] = 0;
+
+ if (kernbuf[len - 1] == '\n')
+ kernbuf[len - 1] = 0;
+
+ if (strcmp(kernbuf, "disabled") == 0 ||
+ strcmp(kernbuf, "Disabled") == 0)
+ value = 0;
+ }
if (value == 0)
sbi->ll_rw_stats_on = 0;
else
sbi->ll_rw_stats_on = 1;
+
spin_lock(&sbi->ll_pp_extent_lock);
for (i = 0; i <= LL_PROCESS_HIST_MAX; i++) {
io_extents->pp_extents[i].pid = 0;
return len;
}
-
LPROC_SEQ_FOPS(ll_rw_extents_stats);
void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid,
return 0;
}
-static ssize_t ll_rw_offset_stats_seq_write(struct file *file, const char *buf,
- size_t len, loff_t *off)
+static ssize_t ll_rw_offset_stats_seq_write(struct file *file,
+ const char __user *buf,
+ size_t len, loff_t *off)
{
struct seq_file *seq = file->private_data;
struct ll_sb_info *sbi = seq->private;
struct ll_rw_process_info *offset_info = sbi->ll_rw_offset_info;
int value = 1, rc = 0;
+ if (len == 0)
+ return -EINVAL;
+
rc = lprocfs_write_helper(buf, len, &value);
- if (rc < 0 && (strcmp(buf, "disabled") == 0 ||
- strcmp(buf, "Disabled") == 0))
- value = 0;
+ if (rc < 0 && len < 16) {
+ char kernbuf[16];
+
+ if (copy_from_user(kernbuf, buf, len))
+ return -EFAULT;
+ kernbuf[len] = 0;
+
+ if (kernbuf[len - 1] == '\n')
+ kernbuf[len - 1] = 0;
+
+ if (strcmp(kernbuf, "disabled") == 0 ||
+ strcmp(kernbuf, "Disabled") == 0)
+ value = 0;
+ }
if (value == 0)
sbi->ll_rw_stats_on = 0;
return mounted;
}
-int ll_unlock(__u32 mode, struct lustre_handle *lockh)
-{
- ldlm_lock_decref(lockh, mode);
-
- return 0;
-}
-
-
/* called from iget5_locked->find_inode() under inode_hash_lock spinlock */
static int ll_test_inode(struct inode *inode, void *opaque)
{
return de;
}
-int ll_lookup_it_finish(struct ptlrpc_request *request,
- struct lookup_intent *it, void *data)
+static int ll_lookup_it_finish(struct ptlrpc_request *request,
+ struct lookup_intent *it,
+ struct inode *parent, struct dentry **de)
{
- struct it_cb_data *icbd = data;
- struct dentry **de = icbd->icbd_childp;
- struct inode *parent = icbd->icbd_parent;
struct inode *inode = NULL;
__u64 bits = 0;
int rc;
struct dentry *save = dentry, *retval;
struct ptlrpc_request *req = NULL;
struct md_op_data *op_data;
- struct it_cb_data icbd;
__u32 opc;
int rc;
if (d_mountpoint(dentry))
CERROR("Tell Peter, lookup on mtpt, it %s\n", LL_IT2STR(it));
- ll_frob_intent(&it, &lookup_it);
+ if (it == NULL || it->it_op == IT_GETXATTR)
+ it = &lookup_it;
if (it->it_op == IT_GETATTR) {
rc = ll_statahead_enter(parent, &dentry, 0);
}
}
- icbd.icbd_childp = &dentry;
- icbd.icbd_parent = parent;
-
if (it->it_op & IT_CREAT)
opc = LUSTRE_OPC_CREATE;
else
if (rc < 0)
GOTO(out, retval = ERR_PTR(rc));
- rc = ll_lookup_it_finish(req, it, &icbd);
+ rc = ll_lookup_it_finish(req, it, parent, &dentry);
if (rc != 0) {
ll_intent_release(it);
GOTO(out, retval = ERR_PTR(rc));
/* We depend on "mode" being set with the proper file type/umask by now */
-static struct inode *ll_create_node(struct inode *dir, const char *name,
- int namelen, const void *data, int datalen,
- int mode, __u64 extra,
- struct lookup_intent *it)
+static struct inode *ll_create_node(struct inode *dir, struct lookup_intent *it)
{
struct inode *inode = NULL;
struct ptlrpc_request *request = NULL;
if (rc)
return rc;
- inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len,
- NULL, 0, mode, 0, it);
+ inode = ll_create_node(dir, it);
if (IS_ERR(inode))
return PTR_ERR(inode);
- if (filename_is_volatile(dentry->d_name.name, dentry->d_name.len, NULL))
- ll_i2info(inode)->lli_volatile = true;
-
d_instantiate(dentry, inode);
return 0;
}
return err;
}
-struct inode_operations ll_dir_inode_operations = {
+const struct inode_operations ll_dir_inode_operations = {
.mknod = ll_mknod,
.atomic_open = ll_atomic_open,
.lookup = ll_lookup_nd,
.get_acl = ll_get_acl,
};
-struct inode_operations ll_special_inode_operations = {
+const struct inode_operations ll_special_inode_operations = {
.setattr = ll_setattr,
.getattr = ll_getattr,
.permission = ll_inode_permission,
OBD_SLAB_FREE(lrp, ll_remote_perm_cachep, sizeof(*lrp));
}
-struct hlist_head *alloc_rmtperm_hash(void)
+static struct hlist_head *alloc_rmtperm_hash(void)
{
struct hlist_head *hash;
int i;
cl_page_put(env, page);
}
- if (io && lcc->lcc_created) {
- cl_io_end(env, io);
- cl_io_unlock(env, io);
- cl_io_iter_fini(env, io);
- cl_io_fini(env, io);
- }
cl_env_put(env, &lcc->lcc_refcheck);
}
}
} else
result = io->ci_result;
- lcc->lcc_created = 1;
}
lcc->lcc_io = io;
if ((file_offset & ~CFS_PAGE_MASK) || (count & ~CFS_PAGE_MASK))
return -EINVAL;
- CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), size=%lu (max %lu), "
- "offset=%lld=%llx, pages %lu (max %lu)\n",
+ CDEBUG(D_VFSTRACE,
+ "VFS Op:inode=%lu/%u(%p), size=%zd (max %lu), offset=%lld=%llx, pages %zd (max %lu)\n",
inode->i_ino, inode->i_generation, inode, count, MAX_DIO_SIZE,
file_offset, file_offset, count >> PAGE_CACHE_SHIFT,
MAX_DIO_SIZE >> PAGE_CACHE_SHIFT);
}
#ifdef CONFIG_MIGRATION
-int ll_migratepage(struct address_space *mapping,
- struct page *newpage, struct page *page
- , enum migrate_mode mode
+static int ll_migratepage(struct address_space *mapping,
+ struct page *newpage, struct page *page,
+ enum migrate_mode mode
)
{
/* Always fail page migration until we have a proper implementation */
#endif
#ifndef MS_HAS_NEW_AOPS
-struct address_space_operations ll_aops = {
- .readpage = ll_readpage,
-// .readpages = ll_readpages,
+const struct address_space_operations ll_aops = {
+ .readpage = ll_readpage,
.direct_IO = ll_direct_IO_26,
.writepage = ll_writepage,
.writepages = ll_writepages,
#ifdef CONFIG_MIGRATION
.migratepage = ll_migratepage,
#endif
- .bmap = NULL
};
#else
-struct address_space_operations_ext ll_aops = {
+const struct address_space_operations_ext ll_aops = {
.orig_aops.readpage = ll_readpage,
// .orig_aops.readpages = ll_readpages,
.orig_aops.direct_IO = ll_direct_IO_26,
#ifdef CONFIG_MIGRATION
.orig_aops.migratepage = ll_migratepage,
#endif
- .orig_aops.bmap = NULL,
.write_begin = ll_write_begin,
.write_end = ll_write_end
};
struct ptlrpc_thread *thread = &sai->sai_agl_thread;
struct l_wait_info lwi = { 0 };
- CDEBUG(D_READA, "agl thread started: [pid %d] [parent %.*s]\n",
- current_pid(), parent->d_name.len, parent->d_name.name);
+ thread->t_pid = current_pid();
+ CDEBUG(D_READA, "agl thread started: sai %p, parent %.*s\n",
+ sai, parent->d_name.len, parent->d_name.name);
atomic_inc(&sbi->ll_agl_total);
spin_lock(&plli->lli_agl_lock);
sai->sai_agl_valid = 1;
- thread_set_flags(thread, SVC_RUNNING);
+ if (thread_is_init(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_agl_lock);
wake_up(&thread->t_ctl_waitq);
spin_unlock(&plli->lli_agl_lock);
wake_up(&thread->t_ctl_waitq);
ll_sai_put(sai);
- CDEBUG(D_READA, "agl thread stopped: [pid %d] [parent %.*s]\n",
- current_pid(), parent->d_name.len, parent->d_name.name);
+ CDEBUG(D_READA, "agl thread stopped: sai %p, parent %.*s\n",
+ sai, parent->d_name.len, parent->d_name.name);
return 0;
}
struct ll_inode_info *plli;
struct task_struct *task;
- CDEBUG(D_READA, "start agl thread: [pid %d] [parent %.*s]\n",
- current_pid(), parent->d_name.len, parent->d_name.name);
+ CDEBUG(D_READA, "start agl thread: sai %p, parent %.*s\n",
+ sai, parent->d_name.len, parent->d_name.name);
plli = ll_i2info(parent->d_inode);
task = kthread_run(ll_agl_thread, parent,
struct ll_dir_chain chain;
struct l_wait_info lwi = { 0 };
- CDEBUG(D_READA, "statahead thread started: [pid %d] [parent %.*s]\n",
- current_pid(), parent->d_name.len, parent->d_name.name);
+ thread->t_pid = current_pid();
+ CDEBUG(D_READA, "statahead thread starting: sai %p, parent %.*s\n",
+ sai, parent->d_name.len, parent->d_name.name);
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);
- thread_set_flags(thread, SVC_RUNNING);
+ if (thread_is_init(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_release_page(page, le32_to_cpu(dp->ldp_flags) &
LDF_COLLIDE);
- sai->sai_in_readpage = 1;
page = ll_get_dir_page(dir, pos, &chain);
- sai->sai_in_readpage = 0;
} else {
LASSERT(le32_to_cpu(dp->ldp_flags) & LDF_COLLIDE);
ll_release_page(page, 1);
spin_unlock(&plli->lli_agl_lock);
wake_up(&agl_thread->t_ctl_waitq);
- CDEBUG(D_READA, "stop agl thread: [pid %d]\n",
- current_pid());
+ CDEBUG(D_READA, "stop agl thread: sai %p pid %u\n",
+ sai, (unsigned int)agl_thread->t_pid);
l_wait_event(agl_thread->t_ctl_waitq,
thread_is_stopped(agl_thread),
&lwi);
wake_up(&thread->t_ctl_waitq);
ll_sai_put(sai);
dput(parent);
- CDEBUG(D_READA, "statahead thread stopped: [pid %d] [parent %.*s]\n",
- current_pid(), parent->d_name.len, parent->d_name.name);
+ CDEBUG(D_READA, "statahead thread stopped: sai %p, parent %.*s\n",
+ sai, parent->d_name.len, parent->d_name.name);
return rc;
}
spin_unlock(&lli->lli_sa_lock);
wake_up(&thread->t_ctl_waitq);
- CDEBUG(D_READA, "stop statahead thread: [pid %d]\n",
- current_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);
CDEBUG(D_READA, "Statahead for dir "DFID" hit "
"ratio too low: hit/miss "LPU64"/"LPU64
", sent/replied "LPU64"/"LPU64", stopping "
- "statahead thread: pid %d\n",
+ "statahead thread\n",
PFID(&lli->lli_fid), sai->sai_hit,
sai->sai_miss, sai->sai_sent,
- sai->sai_replied, current_pid());
+ sai->sai_replied);
spin_lock(&lli->lli_sa_lock);
if (!thread_is_stopped(thread))
thread_set_flags(thread, SVC_STOPPING);
return entry ? 1 : -EAGAIN;
}
- /* if statahead is busy in readdir, help it do post-work */
- while (!ll_sa_entry_stated(entry) &&
- sai->sai_in_readpage &&
- !sa_received_empty(sai))
- ll_post_statahead(sai);
-
if (!ll_sa_entry_stated(entry)) {
sai->sai_index_wait = entry->se_index;
lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(30), NULL,
GOTO(out, rc = -EAGAIN);
}
- CDEBUG(D_READA, "start statahead thread: [pid %d] [parent %.*s]\n",
- current_pid(), parent->d_name.len, parent->d_name.name);
+ CDEBUG(D_READA, "start statahead thread: sai %p, parent %.*s\n",
+ sai, parent->d_name.len, parent->d_name.name);
+ /* 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;
plli = ll_i2info(parent->d_inode);
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 == NULL);
return -EAGAIN;
l_wait_event(thread->t_ctl_waitq,
thread_is_running(thread) || thread_is_stopped(thread),
&lwi);
+ ll_sai_put(sai);
/*
* We don't stat-ahead for the first dirent since we are already in
{
struct ll_inode_info *lli;
ll_stats_ops_tally(ll_s2sbi(sb), LPROC_LL_ALLOC_INODE, 1);
- OBD_SLAB_ALLOC_PTR_GFP(lli, ll_inode_cachep, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(lli, ll_inode_cachep, GFP_NOFS);
if (lli == NULL)
return NULL;
call_rcu(&inode->i_rcu, ll_inode_destroy_callback);
}
-int ll_init_inodecache(void)
+static int ll_init_inodecache(void)
{
ll_inode_cachep = kmem_cache_create("lustre_inode_cache",
sizeof(struct ll_inode_info),
return 0;
}
-void ll_destroy_inodecache(void)
+static void ll_destroy_inodecache(void)
{
kmem_cache_destroy(ll_inode_cachep);
}
void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg));
-int vvp_global_init(void);
-void vvp_global_fini(void);
-
static int __init init_lustre_lite(void)
{
int i, rc, seed[2];
struct inode *inode = dentry->d_inode;
struct ptlrpc_request *request = NULL;
int rc;
- char *symname;
+ char *symname = NULL;
CDEBUG(D_VFSTRACE, "VFS Op\n");
/* Limit the recursive symlink depth to 5 instead of default
#include <obd.h>
#include <lustre_lite.h>
-
+#include "llite_internal.h"
#include "vvp_internal.h"
/*****************************************************************************
* "llite_" (var. "ll_") prefix.
*/
-struct kmem_cache *vvp_thread_kmem;
+static struct kmem_cache *vvp_thread_kmem;
static struct kmem_cache *vvp_session_kmem;
static struct lu_kmem_descr vvp_caches[] = {
{
{
struct vvp_thread_info *info;
- OBD_SLAB_ALLOC_PTR_GFP(info, vvp_thread_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(info, vvp_thread_kmem, GFP_NOFS);
if (info == NULL)
info = ERR_PTR(-ENOMEM);
return info;
{
struct vvp_session *session;
- OBD_SLAB_ALLOC_PTR_GFP(session, vvp_session_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(session, vvp_session_kmem, GFP_NOFS);
if (session == NULL)
session = ERR_PTR(-ENOMEM);
return session;
return result;
}
-struct file_operations vvp_dump_pgcache_file_ops = {
+const struct file_operations vvp_dump_pgcache_file_ops = {
.owner = THIS_MODULE,
.open = vvp_dump_pgcache_seq_open,
.read = seq_read,
struct ccc_object *cl_inode2ccc(struct inode *inode);
-extern struct kmem_cache *vvp_thread_kmem;
+extern const struct file_operations vvp_dump_pgcache_file_ops;
#endif /* VVP_INTERNAL_H */
case CIT_WRITE:
/* don't need lock here to check lli_layout_gen as we have held
* extent lock and GROUP lock has to hold to swap layout */
- if (lli->lli_layout_gen != cio->cui_layout_gen) {
+ if (ll_layout_version_get(lli) != cio->cui_layout_gen) {
io->ci_need_restart = 1;
/* this will return application a short read/write */
io->ci_continue = 0;
vvp_io_fini(env, ios);
}
-enum cl_lock_mode vvp_mode_from_vma(struct vm_area_struct *vma)
+static enum cl_lock_mode vvp_mode_from_vma(struct vm_area_struct *vma)
{
/*
* we only want to hold PW locks if the mmap() can generate
return 0;
}
-int vvp_conf_set(const struct lu_env *env, struct cl_object *obj,
- const struct cl_object_conf *conf)
+static int vvp_conf_set(const struct lu_env *env, struct cl_object *obj,
+ const struct cl_object_conf *conf)
{
struct ll_inode_info *lli = ll_i2info(conf->coc_inode);
if (conf->coc_opc == OBJECT_CONF_INVALIDATE) {
- lli->lli_layout_gen = LL_LAYOUT_GEN_NONE;
+ CDEBUG(D_VFSTRACE, DFID ": losing layout lock\n",
+ PFID(&lli->lli_fid));
+
+ ll_layout_version_set(lli, LL_LAYOUT_GEN_NONE);
+
+ /* Clean up page mmap for this inode.
+ * The reason for us to do this is that if the page has
+ * already been installed into memory space, the process
+ * can access it without interacting with lustre, so this
+ * page may be stale due to layout change, and the process
+ * will never be notified.
+ * This operation is expensive but mmap processes have to pay
+ * a price themselves. */
+ unmap_mapping_range(conf->coc_inode->i_mapping,
+ 0, OBD_OBJECT_EOF, 0);
+
return 0;
}
return 0;
if (conf->u.coc_md != NULL && conf->u.coc_md->lsm != NULL) {
- CDEBUG(D_VFSTRACE, "layout lock change: %u -> %u\n",
- lli->lli_layout_gen,
- conf->u.coc_md->lsm->lsm_layout_gen);
+ CDEBUG(D_VFSTRACE, DFID ": layout version change: %u -> %u\n",
+ PFID(&lli->lli_fid), lli->lli_layout_gen,
+ conf->u.coc_md->lsm->lsm_layout_gen);
lli->lli_has_smd = lsm_has_objects(conf->u.coc_md->lsm);
- lli->lli_layout_gen = conf->u.coc_md->lsm->lsm_layout_gen;
+ ll_layout_version_set(lli, conf->u.coc_md->lsm->lsm_layout_gen);
} else {
- CDEBUG(D_VFSTRACE, "layout lock destroyed: %u.\n",
- lli->lli_layout_gen);
+ CDEBUG(D_VFSTRACE, DFID ": layout nuked: %u.\n",
+ PFID(&lli->lli_fid), lli->lli_layout_gen);
lli->lli_has_smd = false;
- lli->lli_layout_gen = LL_LAYOUT_GEN_EMPTY;
+ ll_layout_version_set(lli, LL_LAYOUT_GEN_EMPTY);
}
return 0;
}
struct ptlrpc_request *req = NULL;
int xattr_type, rc;
struct obd_capa *oc;
- struct rmtacl_ctl_entry *rce = NULL;
#ifdef CONFIG_FS_POSIX_ACL
+ struct rmtacl_ctl_entry *rce = NULL;
posix_acl_xattr_header *new_value = NULL;
ext_acl_xattr_header *acl = NULL;
#endif
if (rc)
return rc;
+ if ((xattr_type == XATTR_ACL_ACCESS_T ||
+ xattr_type == 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))
return -EPROTO;
}
- OBD_SLAB_ALLOC_PTR_GFP(xattr, xattr_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(xattr, xattr_kmem, GFP_NOFS);
if (xattr == NULL) {
CDEBUG(D_CACHE, "failed to allocate xattr\n");
return -ENOMEM;
* \retval 0 @cache is not initialized
* \retval 1 @cache is initialized
*/
-int ll_xattr_cache_valid(struct ll_inode_info *lli)
+static int ll_xattr_cache_valid(struct ll_inode_info *lli)
{
return !!(lli->lli_flags & LLIF_XATTR_CACHE);
}
}
static int lmv_init_ea_size(struct obd_export *exp, int easize,
- int def_easize, int cookiesize)
+ int def_easize, int cookiesize, int def_cookiesize)
{
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
lmv->max_cookiesize = cookiesize;
change = 1;
}
+ if (lmv->max_def_cookiesize < def_cookiesize) {
+ lmv->max_def_cookiesize = def_cookiesize;
+ change = 1;
+ }
if (change == 0)
return 0;
}
rc = md_init_ea_size(lmv->tgts[i]->ltd_exp, easize, def_easize,
- cookiesize);
+ cookiesize, def_cookiesize);
if (rc) {
CERROR("%s: obd_init_ea_size() failed on MDT target %d:"
" rc = %d.\n", obd->obd_name, i, rc);
tgt->ltd_exp = mdc_exp;
lmv->desc.ld_active_tgt_count++;
- md_init_ea_size(tgt->ltd_exp, lmv->max_easize,
- lmv->max_def_easize, lmv->max_cookiesize);
+ md_init_ea_size(tgt->ltd_exp, lmv->max_easize, lmv->max_def_easize,
+ lmv->max_cookiesize, lmv->max_def_cookiesize);
CDEBUG(D_CONFIG, "Connected to %s(%s) successfully (%d)\n",
mdc_obd->obd_name, mdc_obd->obd_uuid.uuid,
spin_unlock(&lmv->lmv_lock);
} else {
int easize = sizeof(struct lmv_stripe_md) +
- lmv->desc.ld_tgt_count *
- sizeof(struct lu_fid);
- lmv_init_ea_size(obd->obd_self_export, easize, 0, 0);
+ lmv->desc.ld_tgt_count * sizeof(struct lu_fid);
+ lmv_init_ea_size(obd->obd_self_export, easize, 0, 0, 0);
}
}
class_export_put(lmv->exp);
lmv->connected = 1;
easize = lmv_get_easize(lmv);
- lmv_init_ea_size(obd->obd_self_export, easize, 0, 0);
+ lmv_init_ea_size(obd->obd_self_export, easize, 0, 0, 0);
lmv_init_unlock(lmv);
return 0;
return 0;
}
return -EINVAL;
- } else if (KEY_IS(KEY_MAX_EASIZE) || KEY_IS(KEY_CONN_DATA)) {
+ } else if (KEY_IS(KEY_MAX_EASIZE) ||
+ KEY_IS(KEY_DEFAULT_EASIZE) ||
+ KEY_IS(KEY_MAX_COOKIESIZE) ||
+ KEY_IS(KEY_DEFAULT_COOKIESIZE) ||
+ KEY_IS(KEY_CONN_DATA)) {
rc = lmv_check_connect(obd);
if (rc)
return rc;
LPROC_SEQ_FOPS_RO_TYPE(lmv, uuid);
struct lprocfs_vars lprocfs_lmv_obd_vars[] = {
- { "numobd", &lmv_numobd_fops, 0, 0 },
- { "placement", &lmv_placement_fops, 0, 0 },
- { "activeobd", &lmv_activeobd_fops, 0, 0 },
- { "uuid", &lmv_uuid_fops, 0, 0 },
- { "desc_uuid", &lmv_desc_uuid_fops, 0, 0 },
- { 0 }
+ { "numobd", &lmv_numobd_fops, NULL, 0 },
+ { "placement", &lmv_placement_fops, NULL, 0 },
+ { "activeobd", &lmv_activeobd_fops, NULL, 0 },
+ { "uuid", &lmv_uuid_fops, NULL, 0 },
+ { "desc_uuid", &lmv_desc_uuid_fops, NULL, 0 },
+ { NULL }
};
LPROC_SEQ_FOPS_RO_TYPE(lmv, numrefs);
static struct lprocfs_vars lprocfs_lmv_module_vars[] = {
- { "num_refs", &lmv_numrefs_fops, 0, 0 },
- { 0 }
+ { "num_refs", &lmv_numrefs_fops, NULL, 0 },
+ { NULL }
};
struct file_operations lmv_proc_target_fops = {
obj-$(CONFIG_LUSTRE_FS) += lov.o
-lov-y := lov_log.o lov_obd.o lov_pack.o lov_offset.o lov_merge.o \
+lov-y := lov_obd.o lov_pack.o lov_offset.o lov_merge.o \
lov_request.o lov_ea.o lov_dev.o lov_object.o lov_page.o \
lov_lock.o lov_io.o lovsub_dev.o lovsub_object.o lovsub_page.o \
lovsub_lock.o lovsub_io.o lov_pool.o
{
struct lov_thread_info *info;
- OBD_SLAB_ALLOC_PTR_GFP(info, lov_thread_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(info, lov_thread_kmem, GFP_NOFS);
if (info != NULL)
INIT_LIST_HEAD(&info->lti_closure.clc_list);
else
{
struct lov_session *info;
- OBD_SLAB_ALLOC_PTR_GFP(info, lov_session_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(info, lov_session_kmem, GFP_NOFS);
if (info == NULL)
info = ERR_PTR(-ENOMEM);
return info;
struct lov_req *lr;
int result;
- OBD_SLAB_ALLOC_PTR_GFP(lr, lov_req_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(lr, lov_req_kmem, GFP_NOFS);
if (lr != NULL) {
cl_req_slice_add(req, &lr->lr_cl, dev, &lov_req_ops);
result = 0;
#include <linux/libcfs/libcfs.h>
#include <obd_class.h>
-#include <obd_lov.h>
#include <lustre/lustre_idl.h>
#include "lov_internal.h"
return NULL;
for (i = 0; i < stripe_count; i++) {
- OBD_SLAB_ALLOC_PTR_GFP(loi, lov_oinfo_slab, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(loi, lov_oinfo_slab, GFP_NOFS);
if (loi == NULL)
goto err;
lsm->lsm_oinfo[i] = loi;
.lsm_lmm_verify = lsm_lmm_verify_v3,
.lsm_unpackmd = lsm_unpackmd_v3,
};
+
+void dump_lsm(unsigned int level, const struct lov_stripe_md *lsm)
+{
+ CDEBUG(level, "lsm %p, objid "DOSTID", maxbytes "LPX64", magic 0x%08X,"
+ " stripe_size %u, stripe_count %u, refc: %d,"
+ " layout_gen %u, pool ["LOV_POOLNAMEF"]\n", lsm,
+ POSTID(&lsm->lsm_oi), lsm->lsm_maxbytes, lsm->lsm_magic,
+ lsm->lsm_stripe_size, lsm->lsm_stripe_count,
+ atomic_read(&lsm->lsm_refc), lsm->lsm_layout_gen,
+ lsm->lsm_pool_name);
+}
#define LOV_INTERNAL_H
#include <obd_class.h>
-#include <obd_lov.h>
#include <lustre/lustre_user.h>
+/* lov_do_div64(a, b) returns a % b, and a = a / b.
+ * The 32-bit code is LOV-specific due to knowing about stripe limits in
+ * order to reduce the divisor to a 32-bit number. If the divisor is
+ * already a 32-bit value the compiler handles this directly. */
+#if BITS_PER_LONG == 64
+# define lov_do_div64(n, base) ({ \
+ uint64_t __base = (base); \
+ uint64_t __rem; \
+ __rem = ((uint64_t)(n)) % __base; \
+ (n) = ((uint64_t)(n)) / __base; \
+ __rem; \
+})
+#elif BITS_PER_LONG == 32
+# define lov_do_div64(n, base) ({ \
+ uint64_t __rem; \
+ if ((sizeof(base) > 4) && (((base) & 0xffffffff00000000ULL) != 0)) { \
+ int __remainder; \
+ LASSERTF(!((base) & (LOV_MIN_STRIPE_SIZE - 1)), "64 bit lov " \
+ "division %llu / %llu\n", (n), (uint64_t)(base)); \
+ __remainder = (n) & (LOV_MIN_STRIPE_SIZE - 1); \
+ (n) >>= LOV_MIN_STRIPE_BITS; \
+ __rem = do_div(n, (base) >> LOV_MIN_STRIPE_BITS); \
+ __rem <<= LOV_MIN_STRIPE_BITS; \
+ __rem += __remainder; \
+ } else { \
+ __rem = do_div(n, base); \
+ } \
+ __rem; \
+})
+#endif
+
struct lov_lock_handles {
struct portals_handle llh_handle;
atomic_t llh_refcount;
__u32 *indexp, int *genp);
int lov_del_target(struct obd_device *obd, __u32 index,
struct obd_uuid *uuidp, int gen);
-/* lov_log.c */
-int lov_llog_init(struct obd_device *obd, struct obd_llog_group *olg,
- struct obd_device *tgt, int *idx);
-int lov_llog_finish(struct obd_device *obd, int count);
/* lov_pack.c */
int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmm,
/* lov_ea.c */
struct lov_stripe_md *lsm_alloc_plain(__u16 stripe_count, int *size);
void lsm_free_plain(struct lov_stripe_md *lsm);
+void dump_lsm(unsigned int level, const struct lov_stripe_md *lsm);
int lovea_destroy_object(struct lov_obd *lov, struct lov_stripe_md *lsm,
struct obdo *oa, void *data);
LASSERT(idx < lck->lls_nr);
- OBD_SLAB_ALLOC_PTR_GFP(link, lov_lock_link_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(link, lov_lock_link_kmem, GFP_NOFS);
if (link != NULL) {
struct lov_sublock_env *subenv;
struct lov_lock_sub *lls;
}
}
LASSERT(nr == lck->lls_nr);
- /*
- * Then, create sub-locks. Once at least one sub-lock was created,
- * top-lock can be reached by other threads.
- */
- for (i = 0; i < lck->lls_nr; ++i) {
- struct cl_lock *sublock;
- struct lov_lock_link *link;
- if (lck->lls_sub[i].sub_lock == NULL) {
- sublock = lov_sublock_alloc(env, io, lck, i, &link);
- if (IS_ERR(sublock)) {
- result = PTR_ERR(sublock);
- break;
- }
- cl_lock_get_trust(sublock);
- cl_lock_mutex_get(env, sublock);
- cl_lock_mutex_get(env, parent);
- /*
- * recheck under mutex that sub-lock wasn't created
- * concurrently, and that top-lock is still alive.
- */
- if (lck->lls_sub[i].sub_lock == NULL &&
- parent->cll_state < CLS_FREEING) {
- lov_sublock_adopt(env, lck, sublock, i, link);
- cl_lock_mutex_put(env, parent);
- } else {
- OBD_SLAB_FREE_PTR(link, lov_lock_link_kmem);
- cl_lock_mutex_put(env, parent);
- cl_lock_unhold(env, sublock,
- "lov-parent", parent);
- }
- cl_lock_mutex_put(env, sublock);
- cl_lock_put(env, sublock);
- }
- }
/*
* Some sub-locks can be missing at this point. This is not a problem,
* because enqueue will create them anyway. Main duty of this function
static int lov_sublock_fill(const struct lu_env *env, struct cl_lock *parent,
struct cl_io *io, struct lov_lock *lck, int idx)
{
- struct lov_lock_link *link;
+ struct lov_lock_link *link = NULL;
struct cl_lock *sublock;
int result;
struct lov_lock *lck;
int result;
- OBD_SLAB_ALLOC_PTR_GFP(lck, lov_lock_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(lck, lov_lock_kmem, GFP_NOFS);
if (lck != NULL) {
cl_lock_slice_add(lock, &lck->lls_cl, obj, &lov_lock_ops);
result = lov_lock_sub_init(env, lck, io);
struct lov_lock *lck;
int result = -ENOMEM;
- OBD_SLAB_ALLOC_PTR_GFP(lck, lov_lock_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(lck, lov_lock_kmem, GFP_NOFS);
if (lck != NULL) {
cl_lock_slice_add(lock, &lck->lls_cl, obj, &lov_empty_lock_ops);
lck->lls_orig = lock->cll_descr;
+++ /dev/null
-/*
- * 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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * 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/lov/lov_log.c
- *
- * Author: Phil Schwan <phil@clusterfs.com>
- * Author: Peter Braam <braam@clusterfs.com>
- * Author: Mike Shaver <shaver@clusterfs.com>
- */
-
-#define DEBUG_SUBSYSTEM S_LOV
-#include <linux/libcfs/libcfs.h>
-
-#include <obd_support.h>
-#include <lustre_lib.h>
-#include <lustre_net.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_dlm.h>
-#include <lustre_mds.h>
-#include <obd_class.h>
-#include <obd_lov.h>
-#include <obd_ost.h>
-#include <lprocfs_status.h>
-#include <lustre_log.h>
-
-#include "lov_internal.h"
-
-/* Add log records for each OSC that this object is striped over, and return
- * cookies for each one. We _would_ have nice abstraction here, except that
- * we need to keep cookies in stripe order, even if some are NULL, so that
- * the right cookies are passed back to the right OSTs at the client side.
- * Unset cookies should be all-zero (which will never occur naturally). */
-static int lov_llog_origin_add(const struct lu_env *env,
- struct llog_ctxt *ctxt,
- struct llog_rec_hdr *rec,
- struct lov_stripe_md *lsm,
- struct llog_cookie *logcookies, int numcookies)
-{
- struct obd_device *obd = ctxt->loc_obd;
- struct lov_obd *lov = &obd->u.lov;
- int i, rc = 0, cookies = 0;
-
- LASSERTF(logcookies && numcookies >= lsm->lsm_stripe_count,
- "logcookies %p, numcookies %d lsm->lsm_stripe_count %d \n",
- logcookies, numcookies, lsm->lsm_stripe_count);
-
- for (i = 0; i < lsm->lsm_stripe_count; i++) {
- struct lov_oinfo *loi = lsm->lsm_oinfo[i];
- struct obd_device *child =
- lov->lov_tgts[loi->loi_ost_idx]->ltd_exp->exp_obd;
- struct llog_ctxt *cctxt = llog_get_context(child, ctxt->loc_idx);
-
- /* fill mds unlink/setattr log record */
- switch (rec->lrh_type) {
- case MDS_UNLINK_REC: {
- struct llog_unlink_rec *lur = (struct llog_unlink_rec *)rec;
- lur->lur_oid = ostid_id(&loi->loi_oi);
- lur->lur_oseq = (__u32)ostid_seq(&loi->loi_oi);
- break;
- }
- case MDS_SETATTR64_REC: {
- struct llog_setattr64_rec *lsr = (struct llog_setattr64_rec *)rec;
- lsr->lsr_oi = loi->loi_oi;
- break;
- }
- default:
- break;
- }
-
- /* inject error in llog_obd_add() below */
- if (OBD_FAIL_CHECK(OBD_FAIL_MDS_FAIL_LOV_LOG_ADD)) {
- llog_ctxt_put(cctxt);
- cctxt = NULL;
- }
- rc = llog_obd_add(env, cctxt, rec, NULL, logcookies + cookies,
- numcookies - cookies);
- llog_ctxt_put(cctxt);
- if (rc < 0) {
- CERROR("Can't add llog (rc = %d) for stripe %d\n",
- rc, cookies);
- memset(logcookies + cookies, 0,
- sizeof(struct llog_cookie));
- rc = 1; /* skip this cookie */
- }
- /* Note that rc is always 1 if llog_obd_add was successful */
- cookies += rc;
- }
- return cookies;
-}
-
-static int lov_llog_origin_connect(struct llog_ctxt *ctxt,
- struct llog_logid *logid,
- struct llog_gen *gen,
- struct obd_uuid *uuid)
-{
- struct obd_device *obd = ctxt->loc_obd;
- struct lov_obd *lov = &obd->u.lov;
- int i, rc = 0, err = 0;
-
- obd_getref(obd);
- for (i = 0; i < lov->desc.ld_tgt_count; i++) {
- struct obd_device *child;
- struct llog_ctxt *cctxt;
-
- if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active)
- continue;
- if (uuid && !obd_uuid_equals(uuid, &lov->lov_tgts[i]->ltd_uuid))
- continue;
- CDEBUG(D_CONFIG, "connect %d/%d\n", i, lov->desc.ld_tgt_count);
- child = lov->lov_tgts[i]->ltd_exp->exp_obd;
- cctxt = llog_get_context(child, ctxt->loc_idx);
- rc = llog_connect(cctxt, logid, gen, uuid);
- llog_ctxt_put(cctxt);
-
- if (rc) {
- CERROR("error osc_llog_connect tgt %d (%d)\n", i, rc);
- if (!err)
- err = rc;
- }
- }
- obd_putref(obd);
-
- return err;
-}
-
-/* the replicators commit callback */
-static int lov_llog_repl_cancel(const struct lu_env *env,
- struct llog_ctxt *ctxt,
- struct lov_stripe_md *lsm,
- int count, struct llog_cookie *cookies,
- int flags)
-{
- struct lov_obd *lov;
- struct obd_device *obd = ctxt->loc_obd;
- int rc = 0, i;
-
- LASSERT(lsm != NULL);
- LASSERT(count == lsm->lsm_stripe_count);
-
- lov = &obd->u.lov;
- obd_getref(obd);
- for (i = 0; i < count; i++, cookies++) {
- struct lov_oinfo *loi = lsm->lsm_oinfo[i];
- struct obd_device *child =
- lov->lov_tgts[loi->loi_ost_idx]->ltd_exp->exp_obd;
- struct llog_ctxt *cctxt =
- llog_get_context(child, ctxt->loc_idx);
- int err;
-
- err = llog_cancel(env, cctxt, NULL, 1, cookies, flags);
- llog_ctxt_put(cctxt);
- if (err && lov->lov_tgts[loi->loi_ost_idx]->ltd_active) {
- CERROR("%s: objid "DOSTID" subobj "DOSTID
- " on OST idx %d: rc = %d\n",
- obd->obd_name, POSTID(&lsm->lsm_oi),
- POSTID(&loi->loi_oi), loi->loi_ost_idx, err);
- if (!rc)
- rc = err;
- }
- }
- obd_putref(obd);
- return rc;
-}
-
-static struct llog_operations lov_mds_ost_orig_logops = {
- .lop_obd_add = lov_llog_origin_add,
- .lop_connect = lov_llog_origin_connect,
-};
-
-static struct llog_operations lov_size_repl_logops = {
- .lop_cancel = lov_llog_repl_cancel,
-};
-
-int lov_llog_init(struct obd_device *obd, struct obd_llog_group *olg,
- struct obd_device *disk_obd, int *index)
-{
- struct lov_obd *lov = &obd->u.lov;
- struct obd_device *child;
- int i, rc = 0;
-
- LASSERT(olg == &obd->obd_olg);
- rc = llog_setup(NULL, obd, olg, LLOG_MDS_OST_ORIG_CTXT, disk_obd,
- &lov_mds_ost_orig_logops);
- if (rc)
- return rc;
-
- rc = llog_setup(NULL, obd, olg, LLOG_SIZE_REPL_CTXT, disk_obd,
- &lov_size_repl_logops);
- if (rc)
- GOTO(err_cleanup, rc);
-
- obd_getref(obd);
- /* count may not match lov->desc.ld_tgt_count during dynamic ost add */
- for (i = 0; i < lov->desc.ld_tgt_count; i++) {
- if (!lov->lov_tgts[i])
- continue;
-
- if (index && i != *index)
- continue;
-
- child = lov->lov_tgts[i]->ltd_obd;
- rc = obd_llog_init(child, &child->obd_olg, disk_obd, &i);
- if (rc)
- CERROR("error osc_llog_init idx %d osc '%s' tgt '%s' "
- "(rc=%d)\n", i, child->obd_name,
- disk_obd->obd_name, rc);
- rc = 0;
- }
- obd_putref(obd);
- GOTO(err_cleanup, rc);
-err_cleanup:
- if (rc) {
- struct llog_ctxt *ctxt =
- llog_get_context(obd, LLOG_SIZE_REPL_CTXT);
- if (ctxt)
- llog_cleanup(NULL, ctxt);
- ctxt = llog_get_context(obd, LLOG_MDS_OST_ORIG_CTXT);
- if (ctxt)
- llog_cleanup(NULL, ctxt);
- }
- return rc;
-}
-
-int lov_llog_finish(struct obd_device *obd, int count)
-{
- struct llog_ctxt *ctxt;
-
- /* cleanup our llogs only if the ctxts have been setup
- * (client lov doesn't setup, mds lov does). */
- ctxt = llog_get_context(obd, LLOG_MDS_OST_ORIG_CTXT);
- if (ctxt)
- llog_cleanup(NULL, ctxt);
-
- ctxt = llog_get_context(obd, LLOG_SIZE_REPL_CTXT);
- if (ctxt)
- llog_cleanup(NULL, ctxt);
-
- /* lov->tgt llogs are cleaned during osc_cleanup. */
- return 0;
-}
#include <linux/libcfs/libcfs.h>
#include <obd_class.h>
-#include <obd_lov.h>
-
#include "lov_internal.h"
/** Merge the lock value block(&lvb) attributes and KMS from each of the
int i;
int rc = 0;
- LASSERT(spin_is_locked(&lsm->lsm_lock));
+ assert_spin_locked(&lsm->lsm_lock);
LASSERT(lsm->lsm_lock_owner == current_pid());
CDEBUG(D_INODE, "MDT ID "DOSTID" initial value: s="LPU64" m="LPU64
int stripe = 0;
__u64 kms;
- LASSERT(spin_is_locked(&lsm->lsm_lock));
+ assert_spin_locked(&lsm->lsm_lock);
LASSERT(lsm->lsm_lock_owner == current_pid());
if (shrink) {
#include <lustre/lustre_idl.h>
#include <lustre_dlm.h>
#include <lustre_mds.h>
-#include <lustre_debug.h>
#include <obd_class.h>
-#include <obd_lov.h>
#include <obd_ost.h>
#include <lprocfs_status.h>
#include <lustre_param.h>
#include <cl_object.h>
#include <lclient.h> /* for cl_client_lru */
#include <lustre/ll_fiemap.h>
-#include <lustre_log.h>
#include <lustre_fid.h>
#include "lov_internal.h"
if (*val != 0)
LCONSOLE_INFO("Increasing default stripe size to "
"minimum %u\n",
- LOV_DEFAULT_STRIPE_SIZE);
- *val = LOV_DEFAULT_STRIPE_SIZE;
+ LOV_DESC_STRIPE_SIZE_DEFAULT);
+ *val = LOV_DESC_STRIPE_SIZE_DEFAULT;
} else if (*val & (LOV_MIN_STRIPE_SIZE - 1)) {
*val &= ~(LOV_MIN_STRIPE_SIZE - 1);
LCONSOLE_WARN("Changing default stripe size to "LPU64" (a "
void lov_fix_desc_qos_maxage(__u32 *val)
{
- /* fix qos_maxage */
if (*val == 0)
- *val = QOS_DEFAULT_MAXAGE;
+ *val = LOV_DESC_QOS_MAXAGE_DEFAULT;
}
void lov_fix_desc(struct lov_desc *desc)
}
break;
}
- case OBD_CLEANUP_EXPORTS:
- rc = obd_llog_finish(obd, 0);
- if (rc != 0)
- CERROR("failed to cleanup llogging subsystems\n");
+ default:
break;
}
+
return rc;
}
if (fm_end_offset == -EINVAL)
GOTO(out, rc = -EINVAL);
+ if (fiemap_count_to_size(fiemap->fm_extent_count) > *vallen)
+ fiemap->fm_extent_count = fiemap_size_to_count(*vallen);
if (fiemap->fm_extent_count == 0) {
get_num_extents = 1;
count_local = 0;
}
-
/* Check each stripe */
for (cur_stripe = start_stripe, i = 0; i < stripe_count;
i++, cur_stripe = (cur_stripe + 1) % lsm->lsm_stripe_count) {
.o_get_info = lov_get_info,
.o_set_info_async = lov_set_info_async,
.o_extent_calc = lov_extent_calc,
- .o_llog_init = lov_llog_init,
- .o_llog_finish = lov_llog_finish,
.o_notify = lov_notify,
.o_pool_new = lov_pool_new,
.o_pool_rem = lov_pool_remove,
#define DEBUG_SUBSYSTEM S_LOV
#include "lov_cl_internal.h"
-#include <lustre_debug.h>
/** \addtogroup lov
* @{
struct lov_object *lov;
struct lu_object *obj;
- OBD_SLAB_ALLOC_PTR_GFP(lov, lov_object_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(lov, lov_object_kmem, GFP_NOFS);
if (lov != NULL) {
obj = lov2lu(lov);
lu_object_init(obj, NULL, dev);
#include <linux/libcfs/libcfs.h>
#include <obd_class.h>
-#include <obd_lov.h>
#include "lov_internal.h"
#include <lustre_net.h>
#include <obd.h>
-#include <obd_lov.h>
#include <obd_class.h>
#include <obd_support.h>
#include <lustre/lustre_user.h>
* Anyway, this is pretty inaccurate since ld_tgt_count now
* represents max index and we should rely on the actual number
* of OSTs instead */
- stripe_count = lov_mds_md_stripecnt(lov->lov_ocd.ocd_max_easize,
- lmm_magic);
+ 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;
}
* larger EA sizes */
if (lov->lov_ocd.ocd_connect_flags & OBD_CONNECT_MAX_EASIZE &&
lov->lov_ocd.ocd_max_easize)
- max_stripes = lov_mds_md_stripecnt(lov->lov_ocd.ocd_max_easize,
- magic);
+ max_stripes = lov_mds_md_max_stripe_count(
+ lov->lov_ocd.ocd_max_easize, magic);
if (stripe_count > max_stripes)
stripe_count = max_stripes;
#include <linux/libcfs/libcfs.h>
#include <obd_class.h>
-#include <obd_lov.h>
#include <lustre/lustre_idl.h>
#include "lov_internal.h"
struct lovsub_req *lsr;
int result;
- OBD_SLAB_ALLOC_PTR_GFP(lsr, lovsub_req_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(lsr, lovsub_req_kmem, GFP_NOFS);
if (lsr != NULL) {
cl_req_slice_add(req, &lsr->lsrq_cl, dev, &lovsub_req_ops);
result = 0;
struct lovsub_lock *lsk;
int result;
- OBD_SLAB_ALLOC_PTR_GFP(lsk, lovsub_lock_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(lsk, lovsub_lock_kmem, GFP_NOFS);
if (lsk != NULL) {
INIT_LIST_HEAD(&lsk->lss_parents);
cl_lock_slice_add(lock, &lsk->lss_cl, obj, &lovsub_lock_ops);
struct lovsub_object *los;
struct lu_object *obj;
- OBD_SLAB_ALLOC_PTR_GFP(los, lovsub_object_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(los, lovsub_object_kmem, GFP_NOFS);
if (los != NULL) {
struct cl_object_header *hdr;
mdc_unlink_pack(req, op_data);
req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER,
- obddev->u.cli.cl_max_mds_easize);
+ obddev->u.cli.cl_default_mds_easize);
req_capsule_set_size(&req->rq_pill, &RMF_ACL, RCL_SERVER,
- obddev->u.cli.cl_max_mds_cookiesize);
+ obddev->u.cli.cl_default_mds_cookiesize);
ptlrpc_request_set_replen(req);
return req;
}
OBD_MD_FLRMTPERM : OBD_MD_FLACL);
struct ldlm_intent *lit;
int rc;
+ int easize;
req = ptlrpc_request_alloc(class_exp2cliimp(exp),
&RQF_LDLM_INTENT_GETATTR);
lit = req_capsule_client_get(&req->rq_pill, &RMF_LDLM_INTENT);
lit->opc = (__u64)it->it_op;
+ if (obddev->u.cli.cl_default_mds_easize > 0)
+ easize = obddev->u.cli.cl_default_mds_easize;
+ else
+ easize = obddev->u.cli.cl_max_mds_easize;
+
/* pack the intended request */
- mdc_getattr_pack(req, valid, it->it_flags, op_data,
- obddev->u.cli.cl_max_mds_easize);
+ mdc_getattr_pack(req, valid, it->it_flags, op_data, easize);
- req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER,
- obddev->u.cli.cl_max_mds_easize);
+ req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER, easize);
if (client_is_remote(exp))
req_capsule_set_size(&req->rq_pill, &RMF_ACL, RCL_SERVER,
sizeof(struct mdt_remote_perm));
layout->li_opc = LAYOUT_INTENT_ACCESS;
req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
- obd->u.cli.cl_max_mds_easize);
+ obd->u.cli.cl_default_mds_easize);
ptlrpc_request_set_replen(req);
return req;
}
mdc_put_rpc_lock(obddev->u.cli.cl_rpc_lock, it);
if (rc < 0) {
- CERROR("ldlm_cli_enqueue: %d\n", rc);
+ CDEBUG_LIMIT((rc == -EACCES || rc == -EIDRM) ? D_INFO : D_ERROR,
+ "%s: ldlm_cli_enqueue failed: rc = %d\n",
+ obddev->obd_name, rc);
+
mdc_clear_replay_flag(req, rc);
ptlrpc_req_finished(req);
return rc;
*request = req;
if (rc && req->rq_commit_cb) {
/* Put an extra reference on \var mod on error case. */
- obd_mod_put(*mod);
+ if (mod != NULL && *mod != NULL)
+ obd_mod_put(*mod);
req->rq_commit_cb(req);
}
return rc;
mdc_unlink_pack(req, op_data);
req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER,
- obd->u.cli.cl_max_mds_easize);
+ obd->u.cli.cl_default_mds_easize);
req_capsule_set_size(&req->rq_pill, &RMF_LOGCOOKIES, RCL_SERVER,
- obd->u.cli.cl_max_mds_cookiesize);
+ obd->u.cli.cl_default_mds_cookiesize);
ptlrpc_request_set_replen(req);
*request = req;
mdc_rename_pack(req, op_data, old, oldlen, new, newlen);
req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER,
- obd->u.cli.cl_max_mds_easize);
+ obd->u.cli.cl_default_mds_easize);
req_capsule_set_size(&req->rq_pill, &RMF_LOGCOOKIES, RCL_SERVER,
- obd->u.cli.cl_max_mds_cookiesize);
+ obd->u.cli.cl_default_mds_cookiesize);
ptlrpc_request_set_replen(req);
rc = mdc_reint(req, obd->u.cli.cl_rpc_lock, LUSTRE_IMP_FULL);
mdc_close_pack(req, op_data);
req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER,
- obd->u.cli.cl_max_mds_easize);
+ obd->u.cli.cl_default_mds_easize);
req_capsule_set_size(&req->rq_pill, &RMF_LOGCOOKIES, RCL_SERVER,
- obd->u.cli.cl_max_mds_cookiesize);
+ obd->u.cli.cl_default_mds_cookiesize);
ptlrpc_request_set_replen(req);
if (*vallen != sizeof(int))
return -EINVAL;
- mdsize = *(int*)val;
+ mdsize = *(int *)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;
+
+ if (*vallen != sizeof(int))
+ return -EINVAL;
+ default_easize = val;
+ *default_easize = exp->exp_obd->u.cli.cl_default_mds_easize;
+ return 0;
+ } else if (KEY_IS(KEY_MAX_COOKIESIZE)) {
+ int mdsize, *max_cookiesize;
+
+ if (*vallen != sizeof(int))
+ return -EINVAL;
+ mdsize = *(int *)val;
+ if (mdsize > exp->exp_obd->u.cli.cl_max_mds_cookiesize)
+ exp->exp_obd->u.cli.cl_max_mds_cookiesize = mdsize;
+ max_cookiesize = val;
+ *max_cookiesize = exp->exp_obd->u.cli.cl_max_mds_cookiesize;
+ return 0;
+ } else if (KEY_IS(KEY_DEFAULT_COOKIESIZE)) {
+ int *default_cookiesize;
+
+ if (*vallen != sizeof(int))
+ return -EINVAL;
+ default_cookiesize = val;
+ *default_cookiesize =
+ exp->exp_obd->u.cli.cl_default_mds_cookiesize;
+ return 0;
} else if (KEY_IS(KEY_CONN_DATA)) {
struct obd_import *imp = class_exp2cliimp(exp);
struct obd_connect_data *data = val;
}
/* Initialize the default and maximum LOV EA and cookie sizes. This allows
- * us to make MDS RPCs with large enough reply buffers to hold the
- * maximum-sized (= maximum striped) EA and cookie without having to
- * calculate this (via a call into the LOV + OSCs) each time we make an RPC. */
+ * us to make MDS RPCs with large enough reply buffers to hold a default
+ * sized EA and cookie without having to calculate this (via a call into the
+ * LOV + OSCs) each time we make an RPC. The maximum size is also tracked
+ * but not used to avoid wastefully vmalloc()'ing large reply buffers when
+ * 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_easize, int cookiesize, int def_cookiesize)
{
struct obd_device *obd = exp->exp_obd;
struct client_obd *cli = &obd->u.cli;
if (cli->cl_max_mds_cookiesize < cookiesize)
cli->cl_max_mds_cookiesize = cookiesize;
+ if (cli->cl_default_mds_cookiesize < def_cookiesize)
+ cli->cl_default_mds_cookiesize = def_cookiesize;
+
return 0;
}
if (env == NULL)
return -ENOMEM;
- /* The mgc fs exclusion sem. Only one fs can be setup at a time. */
- down(&cli->cl_mgc_sem);
+ /* The mgc fs exclusion mutex. Only one fs can be setup at a time. */
+ mutex_lock(&cli->cl_mgc_mutex);
cfs_cleanup_group_info();
if (rc < 0) {
local_oid_storage_fini(env, cli->cl_mgc_los);
cli->cl_mgc_los = NULL;
- up(&cli->cl_mgc_sem);
+ mutex_unlock(&cli->cl_mgc_mutex);
}
out_env:
lu_env_fini(env);
unlock:
class_decref(obd, "mgc_fs", obd);
- up(&cli->cl_mgc_sem);
+ mutex_unlock(&cli->cl_mgc_mutex);
return 0;
}
func, line);
}
#define cl_lock_trace(level, env, prefix, lock) \
- cl_lock_trace0(level, env, prefix, lock, __FUNCTION__, __LINE__)
+ cl_lock_trace0(level, env, prefix, lock, __func__, __LINE__)
#define RETIP ((unsigned long)__builtin_return_address(0))
struct cl_lock *lock;
struct lu_object_header *head;
- OBD_SLAB_ALLOC_PTR_GFP(lock, cl_lock_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(lock, cl_lock_kmem, GFP_NOFS);
if (lock != NULL) {
atomic_set(&lock->cll_ref, 1);
lock->cll_descr = *descr;
struct cl_object_header *head;
head = cl_object_header(obj);
- LINVRNT(spin_is_locked(&head->coh_lock_guard));
+ assert_spin_locked(&head->coh_lock_guard);
CS_LOCK_INC(obj, lookup);
list_for_each_entry(lock, &head->coh_locks, cll_linkage) {
int matched;
spin_lock(&head->coh_lock_guard);
ghost = cl_lock_lookup(env, obj, io, need);
if (ghost == NULL) {
+ cl_lock_get_trust(lock);
list_add_tail(&lock->cll_linkage,
&head->coh_locks);
spin_unlock(&head->coh_lock_guard);
LINVRNT(cl_lock_invariant(env, lock));
if (lock->cll_state < CLS_FREEING) {
+ bool in_cache;
+
LASSERT(lock->cll_state != CLS_INTRANSIT);
cl_lock_state_set(env, lock, CLS_FREEING);
head = cl_object_header(lock->cll_descr.cld_obj);
spin_lock(&head->coh_lock_guard);
- list_del_init(&lock->cll_linkage);
+ in_cache = !list_empty(&lock->cll_linkage);
+ if (in_cache)
+ list_del_init(&lock->cll_linkage);
spin_unlock(&head->coh_lock_guard);
+ if (in_cache) /* coh_locks cache holds a refcount. */
+ cl_lock_put(env, lock);
+
/*
* From now on, no new references to this lock can be acquired
* by cl_lock_lookup().
struct lu_object_header *top;
int result;
- LASSERT(spin_is_locked(cl_object_attr_guard(obj)));
+ assert_spin_locked(cl_object_attr_guard(obj));
top = obj->co_lu.lo_header;
result = 0;
struct lu_object_header *top;
int result;
- LASSERT(spin_is_locked(cl_object_attr_guard(obj)));
+ assert_spin_locked(cl_object_attr_guard(obj));
top = obj->co_lu.lo_header;
result = 0;
struct lu_env *env;
struct cl_env *cle;
- OBD_SLAB_ALLOC_PTR_GFP(cle, cl_env_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(cle, cl_env_kmem, GFP_NOFS);
if (cle != NULL) {
int rc;
{
struct cl_page *page;
- LASSERT(spin_is_locked(&hdr->coh_page_guard));
+ assert_spin_locked(&hdr->coh_page_guard);
page = radix_tree_lookup(&hdr->coh_tree, index);
if (page != NULL)
struct lu_object_header *head;
OBD_ALLOC_GFP(page, cl_object_header(o)->coh_page_bufsize,
- __GFP_IO);
+ GFP_NOFS);
if (page != NULL) {
int result = 0;
atomic_set(&page->cp_ref, 1);
char obd_jobid_var[JOBSTATS_JOBID_VAR_MAX_LEN + 1] = JOBSTATS_DISABLE;
EXPORT_SYMBOL(obd_jobid_var);
-/* Get jobid of current process by reading the environment variable
- * stored in between the "env_start" & "env_end" of task struct.
- *
- * TODO:
- * It's better to cache the jobid for later use if there is any
- * efficient way, the cl_env code probably could be reused for this
- * purpose.
+char obd_jobid_node[JOBSTATS_JOBID_SIZE + 1];
+
+/* Get jobid of current process from stored variable or calculate
+ * it from pid and user_id.
*
- * If some job scheduler doesn't store jobid in the "env_start/end",
- * then an upcall could be issued here to get the jobid by utilizing
- * the userspace tools/api. Then, the jobid must be cached.
+ * Historically this was also done by reading the environment variable
+ * stored in between the "env_start" & "env_end" of task struct.
+ * This is now deprecated.
*/
int lustre_get_jobid(char *jobid)
{
- int jobid_len = JOBSTATS_JOBID_SIZE;
- int rc = 0;
-
memset(jobid, 0, JOBSTATS_JOBID_SIZE);
/* Jobstats isn't enabled */
if (strcmp(obd_jobid_var, JOBSTATS_DISABLE) == 0)
return 0;
}
- rc = cfs_get_environ(obd_jobid_var, jobid, &jobid_len);
- if (rc) {
- if (rc == -EOVERFLOW) {
- /* For the PBS_JOBID and LOADL_STEP_ID keys (which are
- * variable length strings instead of just numbers), it
- * might make sense to keep the unique parts for JobID,
- * instead of just returning an error. That means a
- * larger temp buffer for cfs_get_environ(), then
- * truncating the string at some separator to fit into
- * the specified jobid_len. Fix later if needed. */
- static bool printed;
- if (unlikely(!printed)) {
- LCONSOLE_ERROR_MSG(0x16b, "%s value too large "
- "for JobID buffer (%d)\n",
- obd_jobid_var, jobid_len);
- printed = true;
- }
- } else {
- CDEBUG((rc == -ENOENT || rc == -EINVAL ||
- rc == -EDEADLK) ? D_INFO : D_ERROR,
- "Get jobid for (%s) failed: rc = %d\n",
- obd_jobid_var, rc);
- }
+ /* Whole node dedicated to single job */
+ if (strcmp(obd_jobid_var, JOBSTATS_NODELOCAL) == 0) {
+ strcpy(jobid, obd_jobid_node);
+ return 0;
}
- return rc;
+
+ return -ENOENT;
}
EXPORT_SYMBOL(lustre_get_jobid);
}
EXPORT_SYMBOL(dump_lniobuf);
-void dump_lsm(int level, struct lov_stripe_md *lsm)
-{
- CDEBUG(level, "lsm %p, objid "DOSTID", maxbytes "LPX64", magic 0x%08X,"
- " stripe_size %u, stripe_count %u, refc: %d,"
- " layout_gen %u, pool ["LOV_POOLNAMEF"]\n", lsm,
- POSTID(&lsm->lsm_oi), lsm->lsm_maxbytes, lsm->lsm_magic,
- lsm->lsm_stripe_size, lsm->lsm_stripe_count,
- atomic_read(&lsm->lsm_refc), lsm->lsm_layout_gen,
- lsm->lsm_pool_name);
-}
-EXPORT_SYMBOL(dump_lsm);
-
#define LPDS sizeof(__u64)
int block_debug_setup(void *addr, int len, __u64 off, __u64 id)
{
{
struct obd_device *obd;
- OBD_SLAB_ALLOC_PTR_GFP(obd, obd_device_cachep, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(obd, obd_device_cachep, GFP_NOFS);
if (obd != NULL) {
obd->obd_magic = OBD_DEVICE_MAGIC;
}
if (strncmp(obd->obd_name, fsname, namelen))
continue;
- class_incref(obd, __FUNCTION__, obd);
+ class_incref(obd, __func__, obd);
read_unlock(&obd_dev_lock);
rc2 = obd_set_info_async(NULL, obd->obd_self_export,
sizeof(KEY_SPTLRPC_CONF),
KEY_SPTLRPC_CONF, 0, NULL, NULL);
rc = rc ? rc : rc2;
- class_decref(obd, __FUNCTION__, obd);
+ class_decref(obd, __func__, obd);
read_lock(&obd_dev_lock);
}
read_unlock(&obd_dev_lock);
OBD_FREE_LARGE(*buf, hdr.ioc_len);
return err;
}
+ if (hdr.ioc_len != data->ioc_len)
+ return -EINVAL;
if (obd_ioctl_is_invalid(data)) {
CERROR("ioctl not correctly formatted\n");
if (obd->obd_stopping)
continue;
- class_incref(obd, __FUNCTION__, current);
+ class_incref(obd, __func__, current);
read_unlock(&obd_dev_lock);
if (obd_health_check(NULL, obd)) {
obd->obd_name);
rc++;
}
- class_decref(obd, __FUNCTION__, current);
+ class_decref(obd, __func__, current);
read_lock(&obd_dev_lock);
}
read_unlock(&obd_dev_lock);
return -EINVAL;
memset(obd_jobid_var, 0, JOBSTATS_JOBID_VAR_MAX_LEN + 1);
+
+ /* This might leave the var invalid on error, which is probably fine.*/
+ if (copy_from_user(obd_jobid_var, buffer, count))
+ return -EFAULT;
+
/* Trim the trailing '\n' if any */
- memcpy(obd_jobid_var, buffer, count - (buffer[count - 1] == '\n'));
+ if (obd_jobid_var[count - 1] == '\n')
+ obd_jobid_var[count - 1] = 0;
+
return count;
}
LPROC_SEQ_FOPS(obd_proc_jobid_var);
+static int obd_proc_jobid_name_seq_show(struct seq_file *m, void *v)
+{
+ return seq_printf(m, "%s\n", obd_jobid_var);
+}
+
+static ssize_t obd_proc_jobid_name_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
+{
+ if (!count || count > JOBSTATS_JOBID_SIZE)
+ return -EINVAL;
+
+ if (copy_from_user(obd_jobid_node, buffer, count))
+ return -EFAULT;
+
+ obd_jobid_node[count] = 0;
+
+ /* Trim the trailing '\n' if any */
+ if (obd_jobid_node[count - 1] == '\n')
+ obd_jobid_node[count - 1] = 0;
+
+ return count;
+}
+LPROC_SEQ_FOPS(obd_proc_jobid_name);
+
/* Root for /proc/fs/lustre */
struct proc_dir_entry *proc_lustre_root = NULL;
EXPORT_SYMBOL(proc_lustre_root);
{ "pinger", &obd_proc_pinger_fops },
{ "health_check", &obd_proc_health_fops },
{ "jobid_var", &obd_proc_jobid_var_fops },
+ { .name = "jobid_name",
+ .fops = &obd_proc_jobid_name_fops},
{ 0 }
};
}
EXPORT_SYMBOL(llog_sync);
-int llog_obd_add(const struct lu_env *env, struct llog_ctxt *ctxt,
- struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
- struct llog_cookie *logcookies, int numcookies)
-{
- int raised, rc;
-
- if (!ctxt) {
- CERROR("No ctxt\n");
- return -ENODEV;
- }
-
- if (ctxt->loc_flags & LLOG_CTXT_FLAG_UNINITIALIZED)
- return -ENXIO;
-
- CTXT_CHECK_OP(ctxt, obd_add, -EOPNOTSUPP);
- raised = cfs_cap_raised(CFS_CAP_SYS_RESOURCE);
- if (!raised)
- cfs_cap_raise(CFS_CAP_SYS_RESOURCE);
- rc = CTXTP(ctxt, obd_add)(env, ctxt, rec, lsm, logcookies,
- numcookies);
- if (!raised)
- cfs_cap_lower(CFS_CAP_SYS_RESOURCE);
- return rc;
-}
-EXPORT_SYMBOL(llog_obd_add);
-
int llog_cancel(const struct lu_env *env, struct llog_ctxt *ctxt,
- struct lov_stripe_md *lsm, int count,
struct llog_cookie *cookies, int flags)
{
int rc;
}
CTXT_CHECK_OP(ctxt, cancel, -EOPNOTSUPP);
- rc = CTXTP(ctxt, cancel)(env, ctxt, lsm, count, cookies, flags);
+ rc = CTXTP(ctxt, cancel)(env, ctxt, cookies, flags);
return rc;
}
EXPORT_SYMBOL(llog_cancel);
int rc;
CDEBUG(D_MOUNT, "Starting obd %s (typ=%s)\n", obdname, type);
- rc = do_lcfg(obdname, 0, LCFG_ATTACH, type, uuid, 0, 0);
+ rc = do_lcfg(obdname, 0, LCFG_ATTACH, type, uuid, NULL, NULL);
if (rc) {
CERROR("%s attach error %d\n", obdname, rc);
return rc;
rc = do_lcfg(obdname, 0, LCFG_SETUP, s1, s2, s3, s4);
if (rc) {
CERROR("%s setup error %d\n", obdname, rc);
- do_lcfg(obdname, 0, LCFG_DETACH, 0, 0, 0, 0);
+ do_lcfg(obdname, 0, LCFG_DETACH, NULL, NULL, NULL, NULL);
}
return rc;
}
lnet_process_id_t id;
while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
rc = do_lcfg(mgcname, id.nid,
- LCFG_ADD_UUID, niduuid, 0,0,0);
+ LCFG_ADD_UUID, niduuid,
+ NULL, NULL, NULL);
}
} else {
/* Use mgsnode= nids */
}
while (class_parse_nid(ptr, &nid, &ptr) == 0) {
rc = do_lcfg(mgcname, nid,
- LCFG_ADD_UUID, niduuid, 0,0,0);
+ LCFG_ADD_UUID, niduuid,
+ NULL, NULL, NULL);
i++;
}
}
ptr = lsi->lsi_lmd->lmd_dev;
while (class_parse_nid(ptr, &nid, &ptr) == 0) {
rc = do_lcfg(mgcname, nid,
- LCFG_ADD_UUID, niduuid, 0,0,0);
+ LCFG_ADD_UUID, niduuid, NULL, NULL, NULL);
i++;
/* Stop at the first failover nid */
if (*ptr == ':')
while (class_parse_nid_quiet(ptr, &nid, &ptr) == 0) {
j++;
rc = do_lcfg(mgcname, nid,
- LCFG_ADD_UUID, niduuid, 0,0,0);
+ LCFG_ADD_UUID, niduuid, NULL, NULL, NULL);
if (*ptr == ':')
break;
}
if (j > 0) {
rc = do_lcfg(mgcname, 0, LCFG_ADD_CONN,
- niduuid, 0, 0, 0);
+ niduuid, NULL, NULL, NULL);
i++;
} else {
/* at ":/fsname" */
for (i = 0; i < lsi->lsi_lmd->lmd_mgs_failnodes; i++) {
sprintf(ptr, "_%x", i);
rc = do_lcfg(LUSTRE_MGC_OBDNAME, 0, LCFG_DEL_UUID,
- niduuid, 0, 0, 0);
+ niduuid, NULL, NULL, NULL);
if (rc)
CERROR("del MDC UUID %s failed: rc = %d\n",
niduuid, rc);
#include <lustre_fid.h>
#include <lustre_acl.h>
#include <lustre_net.h>
-#include <obd_lov.h>
#include "echo_internal.h"
{
struct echo_lock *el;
- OBD_SLAB_ALLOC_PTR_GFP(el, echo_lock_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(el, echo_lock_kmem, GFP_NOFS);
if (el != NULL) {
cl_lock_slice_add(lock, &el->el_cl, obj, &echo_lock_ops);
el->el_object = cl2echo_obj(obj);
/* we're the top dev. */
LASSERT(hdr == NULL);
- OBD_SLAB_ALLOC_PTR_GFP(eco, echo_object_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(eco, echo_object_kmem, GFP_NOFS);
if (eco != NULL) {
struct cl_object_header *hdr = &eco->eo_hdr;
{
struct echo_thread_info *info;
- OBD_SLAB_ALLOC_PTR_GFP(info, echo_thread_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(info, echo_thread_kmem, GFP_NOFS);
if (info == NULL)
info = ERR_PTR(-ENOMEM);
return info;
{
struct echo_session_info *session;
- OBD_SLAB_ALLOC_PTR_GFP(session, echo_session_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(session, echo_session_kmem, GFP_NOFS);
if (session == NULL)
session = ERR_PTR(-ENOMEM);
return session;
int i;
int rc;
int verify;
- int gfp_mask;
+ gfp_t gfp_mask;
int brw_flags = 0;
verify = (ostid_id(&oa->o_oi) != ECHO_PERSISTENT_OBJID &&
}
/* shrink the number of caching pages to a specific number */
-static ssize_t osc_cached_mb_seq_write(struct file *file, const char *buffer,
- size_t count, loff_t *off)
+static ssize_t osc_cached_mb_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
{
struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
struct client_obd *cli = &dev->u.cli;
int pages_number, mult, rc;
+ char kernbuf[128];
+
+ if (count >= sizeof(kernbuf))
+ return -EINVAL;
+
+ if (copy_from_user(kernbuf, buffer, count))
+ return -EFAULT;
+ kernbuf[count] = 0;
mult = 1 << (20 - PAGE_CACHE_SHIFT);
- buffer = lprocfs_find_named_value(buffer, "used_mb:", &count);
+ buffer += lprocfs_find_named_value(kernbuf, "used_mb:", &count) -
+ kernbuf;
rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult);
if (rc)
return rc;
static void osc_consume_write_grant(struct client_obd *cli,
struct brw_page *pga)
{
- LASSERT(spin_is_locked(&cli->cl_loi_list_lock.lock));
+ assert_spin_locked(&cli->cl_loi_list_lock.lock);
LASSERT(!(pga->flag & OBD_BRW_FROM_GRANT));
atomic_inc(&obd_dirty_pages);
cli->cl_dirty += PAGE_CACHE_SIZE;
static void osc_release_write_grant(struct client_obd *cli,
struct brw_page *pga)
{
- LASSERT(spin_is_locked(&cli->cl_loi_list_lock.lock));
+ assert_spin_locked(&cli->cl_loi_list_lock.lock);
if (!(pga->flag & OBD_BRW_FROM_GRANT)) {
return;
}
static inline int osc_object_is_locked(struct osc_object *obj)
{
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
return spin_is_locked(&obj->oo_lock);
+#else
+ /*
+ * It is not perfect to return true all the time.
+ * But since this function is only used for assertion
+ * and checking, it seems OK.
+ */
+ return 1;
+#endif
}
/*
{
struct osc_thread_info *info;
- OBD_SLAB_ALLOC_PTR_GFP(info, osc_thread_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(info, osc_thread_kmem, GFP_NOFS);
if (info == NULL)
info = ERR_PTR(-ENOMEM);
return info;
{
struct osc_session *info;
- OBD_SLAB_ALLOC_PTR_GFP(info, osc_session_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(info, osc_session_kmem, GFP_NOFS);
if (info == NULL)
info = ERR_PTR(-ENOMEM);
return info;
static int osc_io_read_start(const struct lu_env *env,
const struct cl_io_slice *slice)
{
- struct osc_io *oio = cl2osc_io(env, slice);
struct cl_object *obj = slice->cis_obj;
struct cl_attr *attr = &osc_env_info(env)->oti_attr;
int rc = 0;
- if (oio->oi_lockless == 0 && !slice->cis_io->ci_noatime) {
+ if (!slice->cis_io->ci_noatime) {
cl_object_attr_lock(obj);
attr->cat_atime = LTIME_S(CURRENT_TIME);
rc = cl_object_attr_set(env, obj, attr, CAT_ATIME);
static int osc_io_write_start(const struct lu_env *env,
const struct cl_io_slice *slice)
{
- struct osc_io *oio = cl2osc_io(env, slice);
struct cl_object *obj = slice->cis_obj;
struct cl_attr *attr = &osc_env_info(env)->oti_attr;
- int result = 0;
+ int rc = 0;
- if (oio->oi_lockless == 0) {
- OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_DELAY_SETTIME, 1);
- cl_object_attr_lock(obj);
- result = cl_object_attr_get(env, obj, attr);
- if (result == 0) {
- attr->cat_mtime = attr->cat_ctime =
- LTIME_S(CURRENT_TIME);
- result = cl_object_attr_set(env, obj, attr,
- CAT_MTIME | CAT_CTIME);
- }
- cl_object_attr_unlock(obj);
- }
- return result;
+ OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_DELAY_SETTIME, 1);
+ cl_object_attr_lock(obj);
+ attr->cat_mtime = attr->cat_ctime = LTIME_S(CURRENT_TIME);
+ rc = cl_object_attr_set(env, obj, attr, CAT_MTIME | CAT_CTIME);
+ cl_object_attr_unlock(obj);
+
+ return rc;
}
static int osc_fsync_ost(const struct lu_env *env, struct osc_object *obj,
struct osc_req *or;
int result;
- OBD_SLAB_ALLOC_PTR_GFP(or, osc_req_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(or, osc_req_kmem, GFP_NOFS);
if (or != NULL) {
cl_req_slice_add(req, &or->or_cl, dev, &osc_req_ops);
result = 0;
LASSERT(olck->ols_agl);
olck->ols_agl = 0;
+ olck->ols_flags &= ~LDLM_FL_BLOCK_NOWAIT;
rc = osc_lock_enqueue(env, slice, NULL, CEF_ASYNC | CEF_MUST);
if (rc != 0)
return rc;
struct osc_lock *clk;
int result;
- OBD_SLAB_ALLOC_PTR_GFP(clk, osc_lock_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(clk, osc_lock_kmem, GFP_NOFS);
if (clk != NULL) {
__u32 enqflags = lock->cll_descr.cld_enq_flags;
struct osc_object *osc;
struct lu_object *obj;
- OBD_SLAB_ALLOC_PTR_GFP(osc, osc_object_kmem, __GFP_IO);
+ OBD_SLAB_ALLOC_PTR_GFP(osc, osc_object_kmem, GFP_NOFS);
if (osc != NULL) {
obj = osc2lu(osc);
lu_object_init(obj, NULL, dev);
#include <lustre/lustre_user.h>
#include <obd_cksum.h>
#include <obd_ost.h>
-#include <obd_lov.h>
#include <lustre_ha.h>
#include <lprocfs_status.h>
return rc;
}
+struct kmem_cache *request_cache;
+
+int ptlrpc_request_cache_init(void)
+{
+ request_cache = kmem_cache_create("ptlrpc_cache",
+ sizeof(struct ptlrpc_request),
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ return request_cache == NULL ? -ENOMEM : 0;
+}
+
+void ptlrpc_request_cache_fini(void)
+{
+ kmem_cache_destroy(request_cache);
+}
+
+struct ptlrpc_request *ptlrpc_request_cache_alloc(int flags)
+{
+ struct ptlrpc_request *req;
+
+ OBD_SLAB_ALLOC_PTR_GFP(req, request_cache, flags);
+ return req;
+}
+
+void ptlrpc_request_cache_free(struct ptlrpc_request *req)
+{
+ OBD_SLAB_FREE_PTR(req, request_cache);
+}
+
/**
* Wind down request pool \a pool.
* Frees all requests from the pool too
LASSERT(req->rq_reqbuf);
LASSERT(req->rq_reqbuf_len == pool->prp_rq_size);
OBD_FREE_LARGE(req->rq_reqbuf, pool->prp_rq_size);
- OBD_FREE(req, sizeof(*req));
+ ptlrpc_request_cache_free(req);
}
spin_unlock(&pool->prp_lock);
OBD_FREE(pool, sizeof(*pool));
struct lustre_msg *msg;
spin_unlock(&pool->prp_lock);
- OBD_ALLOC(req, sizeof(struct ptlrpc_request));
+ req = ptlrpc_request_cache_alloc(GFP_NOFS);
if (!req)
return;
OBD_ALLOC_LARGE(msg, size);
if (!msg) {
- OBD_FREE(req, sizeof(struct ptlrpc_request));
+ ptlrpc_request_cache_free(req);
return;
}
req->rq_reqbuf = msg;
request = ptlrpc_prep_req_from_pool(pool);
if (!request)
- OBD_ALLOC_PTR(request);
+ request = ptlrpc_request_cache_alloc(GFP_NOFS);
if (request) {
LASSERTF((unsigned long)imp > 0x1000, "%p", imp);
if (request->rq_pool)
__ptlrpc_free_req_to_pool(request);
else
- OBD_FREE_PTR(request);
+ ptlrpc_request_cache_free(request);
}
EXPORT_SYMBOL(ptlrpc_request_free);
if (request->rq_pool)
__ptlrpc_free_req_to_pool(request);
else
- OBD_FREE(request, sizeof(*request));
+ ptlrpc_request_cache_free(request);
}
static int __ptlrpc_req_finished(struct ptlrpc_request *request, int locked);
*/
void ptlrpc_req_finished_with_imp_lock(struct ptlrpc_request *request)
{
- LASSERT(spin_is_locked(&request->rq_import->imp_lock));
+ assert_spin_locked(&request->rq_import->imp_lock);
(void)__ptlrpc_req_finished(request, 1);
}
EXPORT_SYMBOL(ptlrpc_req_finished_with_imp_lock);
bool skip_committed_list = true;
LASSERT(imp != NULL);
-
- LASSERT(spin_is_locked(&imp->imp_lock));
-
+ assert_spin_locked(&imp->imp_lock);
if (imp->imp_peer_committed_transno == imp->imp_last_transno_checked &&
imp->imp_generation == imp->imp_last_generation_checked) {
{
struct list_head *tmp;
- LASSERT(spin_is_locked(&imp->imp_lock));
+ assert_spin_locked(&imp->imp_lock);
if (req->rq_transno == 0) {
DEBUG_REQ(D_EMERG, req, "saving request with zero transno");
return ERR_PTR(-EINVAL);
/* copy some code from deprecated fakereq. */
- OBD_ALLOC_PTR(req);
+ req = ptlrpc_request_cache_alloc(GFP_NOFS);
if (req == NULL) {
CERROR("ptlrpc: run out of memory!\n");
return ERR_PTR(-ENOMEM);
/* We moaned above already... */
return;
}
- OBD_ALLOC_GFP(req, sizeof(*req), ALLOC_ATOMIC_TRY);
+ req = ptlrpc_request_cache_alloc(ALLOC_ATOMIC_TRY);
if (req == NULL) {
CERROR("Can't allocate incoming request descriptor: "
"Dropping %s RPC from %s\n",
switch (SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
case SPTLRPC_SVC_NULL:
vmsg = req->rq_repdata;
+ LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 3);
voff = vmsg->lm_bufcount - 1;
- LASSERT(vmsg && vmsg->lm_bufcount >= 3);
rmsg = req->rq_reqbuf;
+ LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 3);
roff = rmsg->lm_bufcount - 1; /* last segment */
- LASSERT(rmsg && rmsg->lm_bufcount >= 3);
break;
case SPTLRPC_SVC_AUTH:
case SPTLRPC_SVC_INTG:
vmsg = req->rq_repdata;
+ LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 4);
voff = vmsg->lm_bufcount - 2;
- LASSERT(vmsg && vmsg->lm_bufcount >= 4);
rmsg = req->rq_reqbuf;
+ LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 4);
roff = rmsg->lm_bufcount - 2; /* second last segment */
- LASSERT(rmsg && rmsg->lm_bufcount >= 4);
break;
case SPTLRPC_SVC_PRIV:
vmsg = req->rq_repdata;
+ LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 2);
voff = vmsg->lm_bufcount - 1;
- LASSERT(vmsg && vmsg->lm_bufcount >= 2);
rmsg = req->rq_clrbuf;
+ LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 2);
roff = rmsg->lm_bufcount - 1; /* last segment */
- LASSERT(rmsg && rmsg->lm_bufcount >= 2);
break;
default:
LBUG();
static
void ctx_unhash_pf(struct ptlrpc_cli_ctx *ctx, struct hlist_head *freelist)
{
- LASSERT(spin_is_locked(&ctx->cc_sec->ps_lock));
+ assert_spin_locked(&ctx->cc_sec->ps_lock);
LASSERT(atomic_read(&ctx->cc_refcount) > 0);
LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags));
LASSERT(!hlist_unhashed(&ctx->cc_cache));
__u32 idx = gmsg->gum_mechidx;
LASSERT(idx < MECH_MAX);
- LASSERT(spin_is_locked(&upcall_locks[idx]));
+ assert_spin_locked(&upcall_locks[idx]);
if (list_empty(&gmsg->gum_list))
return;
/* Must be called with imp_lock held! */
static void ptlrpc_deactivate_and_unlock_import(struct obd_import *imp)
{
- LASSERT(spin_is_locked(&imp->imp_lock));
+ assert_spin_locked(&imp->imp_lock);
CDEBUG(D_HA, "setting import %s INVALID\n", obd2cli_tgt(imp->imp_obd));
imp->imp_invalid = 1;
struct obd_device *obd = imp->imp_obd;
spin_lock(&imp->imp_lock);
+ if (imp->imp_deactive != 0) {
+ spin_unlock(&imp->imp_lock);
+ return;
+ }
+
imp->imp_invalid = 0;
spin_unlock(&imp->imp_lock);
obd_import_event(obd, imp, IMP_EVENT_ACTIVE);
{
struct ptlrpc_request *req;
int rq_opc, rc = 0;
- int nowait = imp->imp_obd->obd_force;
- if (nowait)
+ if (imp->imp_obd->obd_force)
GOTO(set_state, rc);
switch (imp->imp_connect_op) {
- case OST_CONNECT: rq_opc = OST_DISCONNECT; break;
- case MDS_CONNECT: rq_opc = MDS_DISCONNECT; break;
- case MGS_CONNECT: rq_opc = MGS_DISCONNECT; break;
+ case OST_CONNECT:
+ rq_opc = OST_DISCONNECT;
+ break;
+ case MDS_CONNECT:
+ rq_opc = MDS_DISCONNECT;
+ break;
+ case MGS_CONNECT:
+ rq_opc = MGS_DISCONNECT;
+ break;
default:
- CERROR("don't know how to disconnect from %s (connect_op %d)\n",
- obd2cli_tgt(imp->imp_obd), imp->imp_connect_op);
- return -EINVAL;
+ rc = -EINVAL;
+ CERROR("%s: don't know how to disconnect from %s "
+ "(connect_op %d): rc = %d\n",
+ imp->imp_obd->obd_name, obd2cli_tgt(imp->imp_obd),
+ imp->imp_connect_op, rc);
+ return rc;
}
if (ptlrpc_import_in_recovery(imp)) {
struct l_wait_info lwi;
cfs_duration_t timeout;
-
if (AT_OFF) {
if (imp->imp_server_timeout)
timeout = cfs_time_seconds(obd_timeout / 2);
spin_lock(&imp->imp_lock);
if (imp->imp_state != LUSTRE_IMP_FULL)
GOTO(out, 0);
-
spin_unlock(&imp->imp_lock);
req = ptlrpc_request_alloc_pack(imp, &RQF_MDS_DISCONNECT,
memset(&imp->imp_remote_handle, 0, sizeof(imp->imp_remote_handle));
spin_unlock(&imp->imp_lock);
+ if (rc == -ETIMEDOUT || rc == -ENOTCONN || rc == -ESHUTDOWN)
+ rc = 0;
+
return rc;
}
EXPORT_SYMBOL(ptlrpc_disconnect_import);
{
LASSERT(policy != NULL);
LASSERT(info != NULL);
- LASSERT(spin_is_locked(&policy->pol_nrs->nrs_lock));
+ assert_spin_locked(&policy->pol_nrs->nrs_lock);
memcpy(info->pi_name, policy->pol_desc->pd_name, NRS_POL_NAME_MAX);
* the proc entries under the being destroyed export{}, so I have
* to drop the lock at first here.
* - jay, jxiong@clusterfs.com */
- class_incref(obd, __FUNCTION__, current);
+ class_incref(obd, __func__, current);
if (strncmp(tmpbuf, "nid:", 4) == 0)
obd_export_evict_by_nid(obd, tmpbuf + 4);
else
obd_export_evict_by_uuid(obd, tmpbuf);
- class_decref(obd, __FUNCTION__, current);
+ class_decref(obd, __func__, current);
out:
OBD_FREE(kbuf, BUFLEN);
LASSERT(desc->pd_compat != NULL);
OBD_CPT_ALLOC_GFP(policy, svcpt->scp_service->srv_cptable,
- svcpt->scp_cpt, sizeof(*policy), __GFP_IO);
+ svcpt->scp_cpt, sizeof(*policy), GFP_NOFS);
if (policy == NULL)
return -ENOMEM;
spin_unlock(&svcpt->scp_rep_lock);
memset(rs, 0, svcpt->scp_service->srv_max_reply_size);
+ rs->rs_size = svcpt->scp_service->srv_max_reply_size;
rs->rs_svcpt = svcpt;
rs->rs_prealloc = 1;
out:
void ptlrpc_pinger_commit_expected(struct obd_import *imp)
{
ptlrpc_update_next_ping(imp, 1);
- LASSERT(spin_is_locked(&imp->imp_lock));
+ assert_spin_locked(&imp->imp_lock);
/*
* Avoid reading stale imp_connect_data. When not sure if pings are
* expected or not on next connection, we assume they are not and force
/* client.c */
struct ptlrpc_bulk_desc *ptlrpc_new_bulk(unsigned npages, unsigned max_brw,
unsigned type, unsigned portal);
+int ptlrpc_request_cache_init(void);
+void ptlrpc_request_cache_fini(void);
+struct ptlrpc_request *ptlrpc_request_cache_alloc(int flags);
+void ptlrpc_request_cache_free(struct ptlrpc_request *req);
void ptlrpc_init_xid(void);
/* events.c */
return rc;
cleanup_phase = 1;
+ rc = ptlrpc_request_cache_init();
+ if (rc)
+ GOTO(cleanup, rc);
+ cleanup_phase = 2;
rc = ptlrpc_init_portals();
if (rc)
GOTO(cleanup, rc);
- cleanup_phase = 2;
+
+ cleanup_phase = 3;
rc = ptlrpc_connection_init();
if (rc)
GOTO(cleanup, rc);
- cleanup_phase = 3;
+ cleanup_phase = 4;
ptlrpc_put_connection_superhack = ptlrpc_connection_put;
rc = ptlrpc_start_pinger();
if (rc)
GOTO(cleanup, rc);
- cleanup_phase = 4;
+ cleanup_phase = 5;
rc = ldlm_init();
if (rc)
GOTO(cleanup, rc);
- cleanup_phase = 5;
+ cleanup_phase = 6;
rc = sptlrpc_init();
if (rc)
GOTO(cleanup, rc);
switch (cleanup_phase) {
case 8:
ptlrpc_nrs_fini();
+ /* Fall through */
case 7:
sptlrpc_fini();
- case 5:
+ /* Fall through */
+ case 6:
ldlm_exit();
- case 4:
+ /* Fall through */
+ case 5:
ptlrpc_stop_pinger();
- case 3:
+ /* Fall through */
+ case 4:
ptlrpc_connection_fini();
- case 2:
+ /* Fall through */
+ case 3:
ptlrpc_exit_portals();
+ /* Fall through */
+ case 2:
+ ptlrpc_request_cache_fini();
+ /* Fall through */
case 1:
ptlrpc_hr_fini();
req_layout_fini();
+ /* Fall through */
default: ;
}
ldlm_exit();
ptlrpc_stop_pinger();
ptlrpc_exit_portals();
+ ptlrpc_request_cache_fini();
ptlrpc_hr_fini();
ptlrpc_connection_fini();
}
#include <obd.h>
#include <obd_ost.h>
#include <obd_class.h>
-#include <obd_lov.h> /* for IOC_LOV_SET_OSC_ACTIVE */
#include <linux/list.h>
#include "ptlrpc_internal.h"
int ptlrpc_import_in_recovery(struct obd_import *imp)
{
int in_recovery = 1;
+
spin_lock(&imp->imp_lock);
if (imp->imp_state == LUSTRE_IMP_FULL ||
imp->imp_state == LUSTRE_IMP_CLOSED ||
- imp->imp_state == LUSTRE_IMP_DISCON)
+ imp->imp_state == LUSTRE_IMP_DISCON ||
+ imp->imp_obd->obd_no_recov)
in_recovery = 0;
spin_unlock(&imp->imp_lock);
+
return in_recovery;
}
return 0;
CDEBUG(D_SEC, "found delayed sec adapt expired, do it now\n");
- return sptlrpc_import_sec_adapt(imp, NULL, 0);
+ return sptlrpc_import_sec_adapt(imp, NULL, NULL);
}
static int import_sec_validate_get(struct obd_import *imp,
return -EACCES;
}
- OBD_ALLOC_PTR(req);
+ req = ptlrpc_request_cache_alloc(GFP_NOFS);
if (!req)
return -ENOMEM;
rc = sptlrpc_req_refresh_ctx(req, 0);
LASSERT(list_empty(&req->rq_ctx_chain));
sptlrpc_cli_ctx_put(req->rq_cli_ctx, 1);
- OBD_FREE_PTR(req);
+ ptlrpc_request_cache_free(req);
return rc;
}
int early_bufsz, early_size;
int rc;
- OBD_ALLOC_PTR(early_req);
+ early_req = ptlrpc_request_cache_alloc(GFP_NOFS);
if (early_req == NULL)
return -ENOMEM;
err_buf:
OBD_FREE_LARGE(early_buf, early_bufsz);
err_req:
- OBD_FREE_PTR(early_req);
+ ptlrpc_request_cache_free(early_req);
return rc;
}
sptlrpc_cli_ctx_put(early_req->rq_cli_ctx, 1);
OBD_FREE_LARGE(early_req->rq_repbuf, early_req->rq_repbuf_len);
- OBD_FREE_PTR(early_req);
+ ptlrpc_request_cache_free(early_req);
}
/**************************************************
rc = policy->sp_sops->alloc_rs(req, msglen);
if (unlikely(rc == -ENOMEM)) {
+ struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt;
+ if (svcpt->scp_service->srv_max_reply_size <
+ msglen + sizeof(struct ptlrpc_reply_state)) {
+ /* Just return failure if the size is too big */
+ CERROR("size of message is too big (%zd), %d allowed",
+ msglen + sizeof(struct ptlrpc_reply_state),
+ svcpt->scp_service->srv_max_reply_size);
+ return -ENOMEM;
+ }
+
/* failed alloc, try emergency pool */
- rs = lustre_get_emerg_rs(req->rq_rqbd->rqbd_svcpt);
+ rs = lustre_get_emerg_rs(svcpt);
if (rs == NULL)
return -ENOMEM;
goto out_pools;
for (j = 0; j < PAGES_PER_POOL && alloced < npages; j++) {
- pools[i][j] = alloc_page(__GFP_IO |
+ pools[i][j] = alloc_page(GFP_NOFS |
__GFP_HIGHMEM);
if (pools[i][j] == NULL)
goto out_pools;
static inline void enc_pools_wakeup(void)
{
- LASSERT(spin_is_locked(&page_pools.epp_lock));
+ assert_spin_locked(&page_pools.epp_lock);
LASSERT(page_pools.epp_waitqlen >= 0);
if (unlikely(page_pools.epp_waitqlen)) {
void
ptlrpc_schedule_difficult_reply(struct ptlrpc_reply_state *rs)
{
- LASSERT(spin_is_locked(&rs->rs_svcpt->scp_rep_lock));
- LASSERT(spin_is_locked(&rs->rs_lock));
+ assert_spin_locked(&rs->rs_svcpt->scp_rep_lock);
+ assert_spin_locked(&rs->rs_lock);
LASSERT(rs->rs_difficult);
rs->rs_scheduled_ever = 1; /* flag any notification attempt */
/* NB request buffers use an embedded
* req if the incoming req unlinked the
* MD; this isn't one of them! */
- OBD_FREE(req, sizeof(*req));
+ ptlrpc_request_cache_free(req);
}
}
return;
exp->exp_last_request_time = new_time;
- CDEBUG(D_HA, "updating export %s at "CFS_TIME_T" exp %p\n",
- exp->exp_client_uuid.uuid,
- exp->exp_last_request_time, exp);
/* exports may get disconnected from the chain even though the
export has references, so we must keep the spin lock while
}
newdl = cfs_time_current_sec() + at_get(&svcpt->scp_at_estimate);
- OBD_ALLOC(reqcopy, sizeof(*reqcopy));
+ reqcopy = ptlrpc_request_cache_alloc(GFP_NOFS);
if (reqcopy == NULL)
return -ENOMEM;
OBD_ALLOC_LARGE(reqmsg, req->rq_reqlen);
- if (!reqmsg) {
- OBD_FREE(reqcopy, sizeof(*reqcopy));
- return -ENOMEM;
- }
+ if (!reqmsg)
+ GOTO(out_free, rc = -ENOMEM);
*reqcopy = *req;
reqcopy->rq_reply_state = NULL;
out:
sptlrpc_svc_ctx_decref(reqcopy);
OBD_FREE_LARGE(reqmsg, req->rq_reqlen);
- OBD_FREE(reqcopy, sizeof(*reqcopy));
+out_free:
+ ptlrpc_request_cache_free(reqcopy);
return rc;
}
unsigned long physkb = virt_to_phys(skb);
int cpu_core = nlm_core_id();
int fr_stn_id = cpu_core * 8 + XLR_FB_STN; /* FB to 6th bucket */
+
msg->msg0 = (((u64)1 << 63) | /* End of packet descriptor */
((u64)127 << 54) | /* No Free back */
(u64)skb->len << 40 | /* Length of data */
return;
}
- if (fw_skb->data[1] == 0x01 && fw_skb->data[2] == 0xfc && fw_skb->len >= 10) {
+ if (fw_skb->data[1] == 0x01 && fw_skb->data[2] == 0xfc &&
+ fw_skb->len >= 10) {
BT_DBG("Setting bluetooth address");
err = hci_h4p_bcm_set_bdaddr(info, fw_skb);
if (err < 0) {
static void lcd_clear_fast_s(void)
{
int pos;
+
lcd_addr_x = lcd_addr_y = 0;
lcd_gotoxy();
static void lcd_clear_fast_p8(void)
{
int pos;
+
lcd_addr_x = lcd_addr_y = 0;
lcd_gotoxy();
static void lcd_clear_fast_tilcd(void)
{
int pos;
+
lcd_addr_x = lcd_addr_y = 0;
lcd_gotoxy();
break;
case 'k': { /* kill end of line */
int x;
+
for (x = lcd_addr_x; x < lcd_bwidth; x++)
lcd_write_data(' ');
return processed;
}
+static void lcd_write_char(char c)
+{
+ /* first, we'll test if we're in escape mode */
+ if ((c != '\n') && lcd_escape_len >= 0) {
+ /* yes, let's add this char to the buffer */
+ lcd_escape[lcd_escape_len++] = c;
+ lcd_escape[lcd_escape_len] = 0;
+ } else {
+ /* aborts any previous escape sequence */
+ lcd_escape_len = -1;
+
+ switch (c) {
+ case LCD_ESCAPE_CHAR:
+ /* start of an escape sequence */
+ lcd_escape_len = 0;
+ lcd_escape[lcd_escape_len] = 0;
+ break;
+ case '\b':
+ /* go back one char and clear it */
+ if (lcd_addr_x > 0) {
+ /* check if we're not at the
+ end of the line */
+ if (lcd_addr_x < lcd_bwidth)
+ /* back one char */
+ lcd_write_cmd(0x10);
+ lcd_addr_x--;
+ }
+ /* replace with a space */
+ lcd_write_data(' ');
+ /* back one char again */
+ lcd_write_cmd(0x10);
+ break;
+ case '\014':
+ /* quickly clear the display */
+ lcd_clear_fast();
+ break;
+ case '\n':
+ /* flush the remainder of the current line and
+ go to the beginning of the next line */
+ for (; lcd_addr_x < lcd_bwidth; lcd_addr_x++)
+ lcd_write_data(' ');
+ lcd_addr_x = 0;
+ lcd_addr_y = (lcd_addr_y + 1) % lcd_height;
+ lcd_gotoxy();
+ break;
+ case '\r':
+ /* go to the beginning of the same line */
+ lcd_addr_x = 0;
+ lcd_gotoxy();
+ break;
+ case '\t':
+ /* print a space instead of the tab */
+ lcd_print(' ');
+ break;
+ default:
+ /* simply print this char */
+ lcd_print(c);
+ break;
+ }
+ }
+
+ /* now we'll see if we're in an escape mode and if the current
+ escape sequence can be understood. */
+ if (lcd_escape_len >= 2) {
+ int processed = 0;
+
+ if (!strcmp(lcd_escape, "[2J")) {
+ /* clear the display */
+ lcd_clear_fast();
+ processed = 1;
+ } else if (!strcmp(lcd_escape, "[H")) {
+ /* cursor to home */
+ lcd_addr_x = lcd_addr_y = 0;
+ lcd_gotoxy();
+ processed = 1;
+ }
+ /* codes starting with ^[[L */
+ else if ((lcd_escape_len >= 3) &&
+ (lcd_escape[0] == '[') &&
+ (lcd_escape[1] == 'L')) {
+ processed = handle_lcd_special_code();
+ }
+
+ /* LCD special escape codes */
+ /* flush the escape sequence if it's been processed
+ or if it is getting too long. */
+ if (processed || (lcd_escape_len >= LCD_ESCAPE_LEN))
+ lcd_escape_len = -1;
+ } /* escape codes */
+}
+
static ssize_t lcd_write(struct file *file,
- const char *buf, size_t count, loff_t *ppos)
+ const char __user *buf, size_t count, loff_t *ppos)
{
- const char *tmp = buf;
+ const char __user *tmp = buf;
char c;
- for (; count-- > 0; (ppos ? (*ppos)++ : 0), ++tmp) {
+ for (; count-- > 0; (*ppos)++, tmp++) {
if (!in_interrupt() && (((count + 1) & 0x1f) == 0))
/* let's be a little nice with other processes
that need some CPU */
schedule();
- if (ppos == NULL && file == NULL)
- /* let's not use get_user() from the kernel ! */
- c = *tmp;
- else if (get_user(c, tmp))
+ if (get_user(c, buf))
return -EFAULT;
- /* first, we'll test if we're in escape mode */
- if ((c != '\n') && lcd_escape_len >= 0) {
- /* yes, let's add this char to the buffer */
- lcd_escape[lcd_escape_len++] = c;
- lcd_escape[lcd_escape_len] = 0;
- } else {
- /* aborts any previous escape sequence */
- lcd_escape_len = -1;
-
- switch (c) {
- case LCD_ESCAPE_CHAR:
- /* start of an escape sequence */
- lcd_escape_len = 0;
- lcd_escape[lcd_escape_len] = 0;
- break;
- case '\b':
- /* go back one char and clear it */
- if (lcd_addr_x > 0) {
- /* check if we're not at the
- end of the line */
- if (lcd_addr_x < lcd_bwidth)
- /* back one char */
- lcd_write_cmd(0x10);
- lcd_addr_x--;
- }
- /* replace with a space */
- lcd_write_data(' ');
- /* back one char again */
- lcd_write_cmd(0x10);
- break;
- case '\014':
- /* quickly clear the display */
- lcd_clear_fast();
- break;
- case '\n':
- /* flush the remainder of the current line and
- go to the beginning of the next line */
- for (; lcd_addr_x < lcd_bwidth; lcd_addr_x++)
- lcd_write_data(' ');
- lcd_addr_x = 0;
- lcd_addr_y = (lcd_addr_y + 1) % lcd_height;
- lcd_gotoxy();
- break;
- case '\r':
- /* go to the beginning of the same line */
- lcd_addr_x = 0;
- lcd_gotoxy();
- break;
- case '\t':
- /* print a space instead of the tab */
- lcd_print(' ');
- break;
- default:
- /* simply print this char */
- lcd_print(c);
- break;
- }
- }
-
- /* now we'll see if we're in an escape mode and if the current
- escape sequence can be understood. */
- if (lcd_escape_len >= 2) {
- int processed = 0;
-
- if (!strcmp(lcd_escape, "[2J")) {
- /* clear the display */
- lcd_clear_fast();
- processed = 1;
- } else if (!strcmp(lcd_escape, "[H")) {
- /* cursor to home */
- lcd_addr_x = lcd_addr_y = 0;
- lcd_gotoxy();
- processed = 1;
- }
- /* codes starting with ^[[L */
- else if ((lcd_escape_len >= 3) &&
- (lcd_escape[0] == '[') &&
- (lcd_escape[1] == 'L')) {
- processed = handle_lcd_special_code();
- }
-
- /* LCD special escape codes */
- /* flush the escape sequence if it's been processed
- or if it is getting too long. */
- if (processed || (lcd_escape_len >= LCD_ESCAPE_LEN))
- lcd_escape_len = -1;
- } /* escape codes */
+ lcd_write_char(c);
}
return tmp - buf;
/* public function usable from the kernel for any purpose */
static void panel_lcd_print(const char *s)
{
- if (lcd_enabled && lcd_initialized)
- lcd_write(NULL, s, strlen(s), NULL);
+ const char *tmp = s;
+ int count = strlen(s);
+
+ if (lcd_enabled && lcd_initialized) {
+ for (; count-- > 0; tmp++) {
+ if (!in_interrupt() && (((count + 1) & 0x1f) == 0))
+ /* let's be a little nice with other processes
+ that need some CPU */
+ schedule();
+
+ lcd_write_char(*tmp);
+ }
+ }
}
/* initialize the LCD driver */
*/
static ssize_t keypad_read(struct file *file,
- char *buf, size_t count, loff_t *ppos)
+ char __user *buf, size_t count, loff_t *ppos)
{
unsigned i = *ppos;
- char *tmp = buf;
+ char __user *tmp = buf;
if (keypad_buflen == 0) {
if (file->f_flags & O_NONBLOCK)
if (input->high_timer == 0) {
char *press_str = input->u.kbd.press_str;
+
if (press_str[0]) {
int s = sizeof(input->u.kbd.press_str);
+
keypad_send_key(press_str, s);
}
}
if (input->u.kbd.repeat_str[0]) {
char *repeat_str = input->u.kbd.repeat_str;
+
if (input->high_timer >= KEYPAD_REP_START) {
int s = sizeof(input->u.kbd.repeat_str);
+
input->high_timer -= KEYPAD_REP_DELAY;
keypad_send_key(repeat_str, s);
}
if (input->u.kbd.repeat_str[0]) {
char *repeat_str = input->u.kbd.repeat_str;
+
if (input->high_timer >= KEYPAD_REP_START) {
int s = sizeof(input->u.kbd.repeat_str);
+
input->high_timer -= KEYPAD_REP_DELAY;
keypad_send_key(repeat_str, s);
}
/* call release event */
if (input->type == INPUT_TYPE_STD) {
void (*release_fct)(int) = input->u.std.release_fct;
+
if (release_fct != NULL)
release_fct(input->u.std.release_data);
} else if (input->type == INPUT_TYPE_KBD) {
char *release_str = input->u.kbd.release_str;
+
if (release_str[0]) {
int s = sizeof(input->u.kbd.release_str);
+
keypad_send_key(release_str, s);
}
}
om = im = m = v = 0ULL;
while (*name) {
int in, out, bit, neg;
+
for (in = 0; (in < sizeof(sigtab)) &&
(sigtab[in] != *name); in++)
;
static void keypad_init(void)
{
int keynum;
+
init_waitqueue_head(&keypad_read_wait);
keypad_buflen = 0; /* flushes any eventual noisy keystroke */
unregister_reboot_notifier(&panel_notifier);
if (scan_timer.function != NULL)
- del_timer(&scan_timer);
+ del_timer_sync(&scan_timer);
if (pprt != NULL) {
if (keypad_enabled) {
+++ /dev/null
-config R8187SE
- tristate "RealTek RTL8187SE Wireless LAN NIC driver"
- depends on PCI && WLAN
- depends on m
- select WIRELESS_EXT
- select WEXT_PRIV
- select EEPROM_93CX6
- select CRYPTO
- ---help---
- If built as a module, it will be called r8187se.ko.
+++ /dev/null
-
-#ccflags-y += -DCONFIG_IEEE80211_NOWEP=y
-#ccflags-y += -std=gnu89
-#ccflags-y += -O2
-#CC = gcc
-
-ccflags-y := -DSW_ANTE
-ccflags-y += -DTX_TRACK
-ccflags-y += -DHIGH_POWER
-ccflags-y += -DSW_DIG
-ccflags-y += -DRATE_ADAPT
-
-#enable it for legacy power save, disable it for leisure power save
-ccflags-y += -DENABLE_LPS
-
-
-#ccflags-y := -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
-
-r8187se-y := \
- r8180_core.o \
- r8180_wx.o \
- r8180_rtl8225z2.o \
- r8185b_init.o \
- r8180_dm.o \
- ieee80211/dot11d.o \
- ieee80211/ieee80211_softmac.o \
- ieee80211/ieee80211_rx.o \
- ieee80211/ieee80211_tx.o \
- ieee80211/ieee80211_wx.o \
- ieee80211/ieee80211_module.o \
- ieee80211/ieee80211_softmac_wx.o \
- ieee80211/ieee80211_crypt.o \
- ieee80211/ieee80211_crypt_tkip.o \
- ieee80211/ieee80211_crypt_ccmp.o \
- ieee80211/ieee80211_crypt_wep.o
-
-obj-$(CONFIG_R8187SE) += r8187se.o
-
+++ /dev/null
-TODO:
-- prepare private ieee80211 stack for merge with rtl8192su's version:
- - add hwsec_active flag to struct ieee80211_device
- - add bHwSec flag to cb_desc structure
-- switch to use shared "librtl" instead of private ieee80211 stack
-- switch to use LIB80211
-- switch to use MAC80211
-- use kernel coding style
-- checkpatch.pl fixes
-- sparse fixes
-- integrate with drivers/net/wireless/rtl818x
-
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
+++ /dev/null
-#include "dot11d.h"
-
-void Dot11d_Init(struct ieee80211_device *ieee)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-
- pDot11dInfo->bEnabled = 0;
-
- 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);
- RESET_CIE_WATCHDOG(ieee);
-
- netdev_info(ieee->dev, "Dot11d_Init()\n");
-}
-
-/* Reset to the state as we are just entering a regulatory domain. */
-void Dot11d_Reset(struct ieee80211_device *ieee)
-{
- u32 i;
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-
- /* Clear old channel map */
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- /* Set new channel map */
- for (i = 1; i <= 11; i++)
- (pDot11dInfo->channel_map)[i] = 1;
-
- for (i = 12; i <= 14; i++)
- (pDot11dInfo->channel_map)[i] = 2;
-
- pDot11dInfo->State = DOT11D_STATE_NONE;
- pDot11dInfo->CountryIeLen = 0;
- RESET_CIE_WATCHDOG(ieee);
-}
-
-/*
- * Description:
- * Update country IE from Beacon or Probe Response and configure PHY for
- * operation in the regulatory domain.
- *
- * TODO:
- * Configure Tx power.
- *
- * Assumption:
- * 1. IS_DOT11D_ENABLE() is TRUE.
- * 2. Input IE is an valid one.
- */
-void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
- u16 CoutryIeLen, u8 *pCoutryIe)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 i, j, NumTriples, MaxChnlNum;
- u8 index, MaxTxPowerInDbm;
- PCHNL_TXPOWER_TRIPLE pTriple;
-
- if ((CoutryIeLen - 3)%3 != 0) {
- netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
- Dot11d_Reset(dev);
- return;
- }
-
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- MaxChnlNum = 0;
- NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */
- pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
- for (i = 0; i < NumTriples; i++) {
- if (MaxChnlNum >= pTriple->FirstChnl) {
- /*
- * It is not in a monotonically increasing order,
- * so stop processing.
- */
- netdev_info(dev->dev,
- "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
- Dot11d_Reset(dev);
- return;
- }
- if (MAX_CHANNEL_NUMBER <
- (pTriple->FirstChnl + pTriple->NumChnls)) {
- /*
- * It is not a valid set of channel id,
- * so stop processing
- */
- netdev_info(dev->dev,
- "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
- Dot11d_Reset(dev);
- return;
- }
-
- for (j = 0; j < pTriple->NumChnls; j++) {
- index = pTriple->FirstChnl + j;
- pDot11dInfo->channel_map[index] = 1;
- MaxTxPowerInDbm = pTriple->MaxTxPowerInDbm;
- pDot11dInfo->MaxTxPwrDbmList[index] = MaxTxPowerInDbm;
- MaxChnlNum = pTriple->FirstChnl + j;
- }
-
- pTriple = (PCHNL_TXPOWER_TRIPLE)((u8 *)pTriple + 3);
- }
-#if 1
- netdev_info(dev->dev, "Channel List:");
- for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
- if (pDot11dInfo->channel_map[i] > 0)
- netdev_info(dev->dev, " %d", i);
- netdev_info(dev->dev, "\n");
-#endif
-
- UPDATE_CIE_SRC(dev, pTaddr);
-
- pDot11dInfo->CountryIeLen = CoutryIeLen;
- memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen);
- pDot11dInfo->State = DOT11D_STATE_LEARNED;
-}
-
-u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 MaxTxPwrInDbm = 255;
-
- if (MAX_CHANNEL_NUMBER < Channel) {
- netdev_info(dev->dev, "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
- return MaxTxPwrInDbm;
- }
- if (pDot11dInfo->channel_map[Channel])
- MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
-
- return MaxTxPwrInDbm;
-}
-
-
-void DOT11D_ScanComplete(struct ieee80211_device *dev)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-
- switch (pDot11dInfo->State) {
- case DOT11D_STATE_LEARNED:
- pDot11dInfo->State = DOT11D_STATE_DONE;
- break;
-
- case DOT11D_STATE_DONE:
- if (GET_CIE_WATCHDOG(dev) == 0) {
- /* Reset country IE if previous one is gone. */
- Dot11d_Reset(dev);
- }
- break;
- case DOT11D_STATE_NONE:
- break;
- }
-}
-
-int IsLegalChannel(struct ieee80211_device *dev, u8 channel)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-
- if (MAX_CHANNEL_NUMBER < channel) {
- netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
- return 0;
- }
- if (pDot11dInfo->channel_map[channel] > 0)
- return 1;
- return 0;
-}
-
-int ToLegalChannel(struct ieee80211_device *dev, u8 channel)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 default_chn = 0;
- u32 i = 0;
-
- for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) {
- if (pDot11dInfo->channel_map[i] > 0) {
- default_chn = i;
- break;
- }
- }
-
- if (MAX_CHANNEL_NUMBER < channel) {
- netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
- return default_chn;
- }
-
- if (pDot11dInfo->channel_map[channel] > 0)
- return channel;
-
- return default_chn;
-}
+++ /dev/null
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
-
-#include "ieee80211.h"
-
-/* #define ENABLE_DOT11D */
-
-/* #define DOT11D_MAX_CHNL_NUM 83 */
-
-typedef struct _CHNL_TXPOWER_TRIPLE {
- u8 FirstChnl;
- u8 NumChnls;
- u8 MaxTxPowerInDbm;
-} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
-
-typedef enum _DOT11D_STATE {
- DOT11D_STATE_NONE = 0,
- DOT11D_STATE_LEARNED,
- DOT11D_STATE_DONE,
-} DOT11D_STATE;
-
-typedef struct _RT_DOT11D_INFO {
- /* DECLARE_RT_OBJECT(RT_DOT12D_INFO); */
-
- bool bEnabled; /* dot11MultiDomainCapabilityEnabled */
-
- u16 CountryIeLen; /* > 0 if CountryIeBuf[] contains valid country information element. */
- u8 CountryIeBuf[MAX_IE_LEN];
- u8 CountryIeSrcAddr[6]; /* Source AP of the country IE. */
- u8 CountryIeWatchdog;
-
- u8 channel_map[MAX_CHANNEL_NUMBER+1]; /* !!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */
- /* u8 ChnlListLen; // #Bytes valid in ChnlList[]. */
- /* u8 ChnlList[DOT11D_MAX_CHNL_NUM]; */
- u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
-
- DOT11D_STATE State;
-} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-
-#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1:0)
-#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
-
-#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
-
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-
-#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
- (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
- FALSE : \
- (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
-
-#define CIE_WATCHDOG_TH 1
-#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
-#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
-
-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
-
-void Dot11d_Init(struct ieee80211_device *dev);
-void Dot11d_Reset(struct ieee80211_device *dev);
-void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
- u16 CoutryIeLen, u8 *pCoutryIe);
-u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel);
-void DOT11D_ScanComplete(struct ieee80211_device *dev);
-int IsLegalChannel(struct ieee80211_device *dev, u8 channel);
-int ToLegalChannel(struct ieee80211_device *dev, u8 channel);
-
-#endif /* #ifndef __INC_DOT11D_H */
+++ /dev/null
-/*
- * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
- * remains copyright by the original authors
- *
- * Portions of the merged code are based on Host AP (software wireless
- * LAN access point) driver for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- * Copyright (c) 2004, Intel Corporation
- *
- * Modified for Realtek's wi-fi cards by Andrea Merello
- * <andrea.merello@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. See README and COPYING for
- * more details.
- */
-#ifndef IEEE80211_H
-#define IEEE80211_H
-#include <linux/if_ether.h> /* ETH_ALEN */
-#include <linux/kernel.h> /* ARRAY_SIZE */
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/sched.h>
-#include <linux/semaphore.h>
-#include <linux/wireless.h>
-#include <linux/ieee80211.h>
-#include <linux/interrupt.h>
-
-#define KEY_TYPE_NA 0x0
-#define KEY_TYPE_WEP40 0x1
-#define KEY_TYPE_TKIP 0x2
-#define KEY_TYPE_CCMP 0x4
-#define KEY_TYPE_WEP104 0x5
-
-#define aSifsTime 10
-
-#define MGMT_QUEUE_NUM 5
-
-
-#define IEEE_CMD_SET_WPA_PARAM 1
-#define IEEE_CMD_SET_WPA_IE 2
-#define IEEE_CMD_SET_ENCRYPTION 3
-#define IEEE_CMD_MLME 4
-
-#define IEEE_PARAM_WPA_ENABLED 1
-#define IEEE_PARAM_TKIP_COUNTERMEASURES 2
-#define IEEE_PARAM_DROP_UNENCRYPTED 3
-#define IEEE_PARAM_PRIVACY_INVOKED 4
-#define IEEE_PARAM_AUTH_ALGS 5
-#define IEEE_PARAM_IEEE_802_1X 6
-//It should consistent with the driver_XXX.c
-// David, 2006.9.26
-#define IEEE_PARAM_WPAX_SELECT 7
-//Added for notify the encryption type selection
-// David, 2006.9.26
-#define IEEE_PROTO_WPA 1
-#define IEEE_PROTO_RSN 2
-//Added for notify the encryption type selection
-// David, 2006.9.26
-#define IEEE_WPAX_USEGROUP 0
-#define IEEE_WPAX_WEP40 1
-#define IEEE_WPAX_TKIP 2
-#define IEEE_WPAX_WRAP 3
-#define IEEE_WPAX_CCMP 4
-#define IEEE_WPAX_WEP104 5
-
-#define IEEE_KEY_MGMT_IEEE8021X 1
-#define IEEE_KEY_MGMT_PSK 2
-
-
-
-#define IEEE_MLME_STA_DEAUTH 1
-#define IEEE_MLME_STA_DISASSOC 2
-
-
-#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2
-#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3
-#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4
-#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5
-#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6
-#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7
-
-
-#define IEEE_CRYPT_ALG_NAME_LEN 16
-
-extern int ieee80211_crypto_tkip_init(void);
-extern void ieee80211_crypto_tkip_exit(void);
-
-//by amy for ps
-typedef struct ieee_param {
- u32 cmd;
- u8 sta_addr[ETH_ALEN];
- union {
- struct {
- u8 name;
- u32 value;
- } wpa_param;
- struct {
- u32 len;
- u8 reserved[32];
- u8 data[0];
- } wpa_ie;
- struct{
- int command;
- int reason_code;
- } mlme;
- struct {
- u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
- u8 set_tx;
- u32 err;
- u8 idx;
- u8 seq[8]; /* sequence counter (set: RX, get: TX) */
- u16 key_len;
- u8 key[0];
- } crypt;
-
- } u;
-}ieee_param;
-
-
-#define MSECS(t) msecs_to_jiffies(t)
-#define msleep_interruptible_rtl msleep_interruptible
-
-#define IEEE80211_DATA_LEN 2304
-/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
- 6.2.1.1.2.
-
- The figure in section 7.1.2 suggests a body size of up to 2312
- bytes is allowed, which is a bit confusing, I suspect this
- represents the 2304 bytes of real data, plus a possible 8 bytes of
- WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
-
-#define IEEE80211_3ADDR_LEN 24
-#define IEEE80211_4ADDR_LEN 30
-#define IEEE80211_FCS_LEN 4
-#define IEEE80211_HLEN IEEE80211_4ADDR_LEN
-#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
-#define IEEE80211_MGMT_HDR_LEN 24
-#define IEEE80211_DATA_HDR3_LEN 24
-#define IEEE80211_DATA_HDR4_LEN 30
-
-#define MIN_FRAG_THRESHOLD 256U
-#define MAX_FRAG_THRESHOLD 2346U
-
-/* Frame control field constants */
-#define IEEE80211_FCTL_DSTODS 0x0300 //added by david
-#define IEEE80211_FCTL_WEP 0x4000
-
-/* debug macros */
-
-#ifdef CONFIG_IEEE80211_DEBUG
-extern u32 ieee80211_debug_level;
-#define IEEE80211_DEBUG(level, fmt, args...) \
-do { if (ieee80211_debug_level & (level)) \
- printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-#else
-#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
-#endif /* CONFIG_IEEE80211_DEBUG */
-
-/*
- * To use the debug system;
- *
- * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
- *
- * #define IEEE80211_DL_xxxx VALUE
- *
- * shifting value to the left one bit from the previous entry. xxxx should be
- * the name of the classification (for example, WEP)
- *
- * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
- * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
- * to send output to that classification.
- *
- * To add your debug level to the list of levels seen when you perform
- *
- * % cat /proc/net/ipw/debug_level
- *
- * you simply need to add your entry to the ipw_debug_levels array.
- *
- * If you do not see debug_level in /proc/net/ipw then you do not have
- * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
- *
- */
-
-#define IEEE80211_DL_INFO (1<<0)
-#define IEEE80211_DL_WX (1<<1)
-#define IEEE80211_DL_SCAN (1<<2)
-#define IEEE80211_DL_STATE (1<<3)
-#define IEEE80211_DL_MGMT (1<<4)
-#define IEEE80211_DL_FRAG (1<<5)
-#define IEEE80211_DL_EAP (1<<6)
-#define IEEE80211_DL_DROP (1<<7)
-
-#define IEEE80211_DL_TX (1<<8)
-#define IEEE80211_DL_RX (1<<9)
-
-#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
-#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
-#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
-
-#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
-#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
-//#define IEEE_DEBUG_SCAN IEEE80211_WARNING
-#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
-#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
-#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
-#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
-#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
-#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
-#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
-#include <linux/netdevice.h>
-#include <linux/if_arp.h> /* ARPHRD_ETHER */
-
-#ifndef WIRELESS_SPY
-#define WIRELESS_SPY // enable iwspy support
-#endif
-#include <net/iw_handler.h> // new driver API
-
-#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#endif /* ETH_P_PAE */
-
-#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
-
-#ifndef ETH_P_80211_RAW
-#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
-#endif
-
-/* 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_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
-#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
-
-#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
-#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
-
-#define WLAN_CAPABILITY_BSS (1<<0)
-#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
-
-#define IEEE80211_STATMASK_SIGNAL (1<<0)
-#define IEEE80211_STATMASK_RSSI (1<<1)
-#define IEEE80211_STATMASK_NOISE (1<<2)
-#define IEEE80211_STATMASK_RATE (1<<3)
-#define IEEE80211_STATMASK_WEMASK 0x7
-
-
-#define IEEE80211_CCK_MODULATION (1<<0)
-#define IEEE80211_OFDM_MODULATION (1<<1)
-
-#define IEEE80211_24GHZ_BAND (1<<0)
-#define IEEE80211_52GHZ_BAND (1<<1)
-
-#define IEEE80211_CCK_RATE_LEN 4
-#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
-
-/* this is stolen and modified from the madwifi driver*/
-#define IEEE80211_FC0_TYPE_MASK 0x0c
-#define IEEE80211_FC0_TYPE_DATA 0x08
-#define IEEE80211_FC0_SUBTYPE_MASK 0xB0
-#define IEEE80211_FC0_SUBTYPE_QOS 0x80
-
-#define IEEE80211_QOS_HAS_SEQ(fc) \
- (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
- (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
-
-/* this is stolen from ipw2200 driver */
-#define IEEE_IBSS_MAC_HASH_SIZE 31
-struct ieee_ibss_seq {
- u8 mac[ETH_ALEN];
- u16 seq_num[17];
- u16 frag_num[17];
- unsigned long packet_time[17];
- struct list_head list;
-};
-
-/* 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];
- u8 signalstrength;
- s8 rssi;
- u8 signal;
- u8 noise;
- u16 rate; /* in 100 kbps */
- u8 received_channel;
- u8 control;
- u8 mask;
- u8 freq;
- u16 len;
- u8 nic_type;
-};
-
-/* 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 {
- unsigned long first_frag_time;
- unsigned int seq;
- unsigned int last_frag;
- struct sk_buff *skb;
- u8 src_addr[ETH_ALEN];
- u8 dst_addr[ETH_ALEN];
-};
-
-struct ieee80211_stats {
- unsigned int tx_unicast_frames;
- unsigned int tx_multicast_frames;
- unsigned int tx_fragments;
- unsigned int tx_unicast_octets;
- unsigned int tx_multicast_octets;
- unsigned int tx_deferred_transmissions;
- unsigned int tx_single_retry_frames;
- unsigned int tx_multiple_retry_frames;
- unsigned int tx_retry_limit_exceeded;
- unsigned int tx_discards;
- unsigned int rx_unicast_frames;
- unsigned int rx_multicast_frames;
- unsigned int rx_fragments;
- unsigned int rx_unicast_octets;
- unsigned int rx_multicast_octets;
- unsigned int rx_fcs_errors;
- unsigned int rx_discards_no_buffer;
- unsigned int tx_discards_wrong_sa;
- unsigned int rx_discards_undecryptable;
- unsigned int rx_message_in_msg_fragments;
- unsigned int rx_message_in_bad_msg_fragments;
-};
-
-struct ieee80211_device;
-
-#include "ieee80211_crypt.h"
-
-#define SEC_KEY_1 (1<<0)
-#define SEC_KEY_2 (1<<1)
-#define SEC_KEY_3 (1<<2)
-#define SEC_KEY_4 (1<<3)
-#define SEC_ACTIVE_KEY (1<<4)
-#define SEC_AUTH_MODE (1<<5)
-#define SEC_UNICAST_GROUP (1<<6)
-#define SEC_LEVEL (1<<7)
-#define SEC_ENABLED (1<<8)
-
-#define SEC_LEVEL_0 0 /* None */
-#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
-#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
-#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
-#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
-
-#define WEP_KEYS 4
-#define WEP_KEY_LEN 13
-
-#define WEP_KEY_LEN_MODIF 32
-
-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_MODIF];
- u8 level;
- u16 flags;
-} __attribute__ ((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
-
-*/
-
-/* Management Frame Information Element Types */
-enum {
- MFIE_TYPE_SSID = 0,
- MFIE_TYPE_RATES = 1,
- MFIE_TYPE_FH_SET = 2,
- MFIE_TYPE_DS_SET = 3,
- MFIE_TYPE_CF_SET = 4,
- MFIE_TYPE_TIM = 5,
- MFIE_TYPE_IBSS_SET = 6,
- MFIE_TYPE_COUNTRY = 7,
- MFIE_TYPE_CHALLENGE = 16,
- MFIE_TYPE_ERP = 42,
- MFIE_TYPE_RSN = 48,
- MFIE_TYPE_RATES_EX = 50,
- MFIE_TYPE_GENERIC = 221,
-};
-
-struct ieee80211_header_data {
- __le16 frame_ctl;
- u16 duration_id;
- u8 addr1[6];
- u8 addr2[6];
- u8 addr3[6];
- u16 seq_ctrl;
-};
-
-struct ieee80211_hdr_4addr {
- __le16 frame_ctl;
- u16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- u16 seq_ctl;
- u8 addr4[ETH_ALEN];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addrqos {
- u16 frame_ctl;
- u16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- u16 seq_ctl;
- u16 qos_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_4addrqos {
- u16 frame_ctl;
- u16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- u16 seq_ctl;
- u8 addr4[ETH_ALEN];
- u16 qos_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_info_element_hdr {
- u8 id;
- u8 len;
-} __attribute__ ((packed));
-
-struct ieee80211_info_element {
- u8 id;
- u8 len;
- u8 data[0];
-} __attribute__ ((packed));
-
-struct ieee80211_authentication {
- struct ieee80211_header_data header;
- u16 algorithm;
- u16 transaction;
- u16 status;
- //struct ieee80211_info_element_hdr info_element;
-} __attribute__ ((packed));
-
-struct ieee80211_disassoc_frame {
- struct ieee80211_hdr_3addr header;
- u16 reasoncode;
-} __attribute__ ((packed));
-
-struct ieee80211_probe_request {
- struct ieee80211_header_data header;
- /* struct ieee80211_info_element info_element; */
-} __attribute__ ((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;
-} __attribute__ ((packed));
-
-struct ieee80211_assoc_request_frame {
- struct ieee80211_hdr_3addr header;
- u16 capability;
- u16 listen_interval;
- //u8 current_ap[ETH_ALEN];
- struct ieee80211_info_element_hdr info_element;
-} __attribute__ ((packed));
-
-struct ieee80211_assoc_response_frame {
- struct ieee80211_hdr_3addr header;
- u16 capability;
- u16 status;
- u16 aid;
- struct ieee80211_info_element info_element; /* supported rates */
-} __attribute__ ((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
-
-/* 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 ((u8)12)
-#define MAX_RATES_EX_LENGTH ((u8)16)
-
-#define MAX_NETWORK_COUNT 128
-
-#define MAX_CHANNEL_NUMBER 165
-
-#define IEEE80211_SOFTMAC_SCAN_TIME 100 /* (HZ / 2) */
-#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
-
-#define CRC_LENGTH 4U
-
-#define MAX_WPA_IE_LEN 64
-
-#define NETWORK_EMPTY_ESSID (1 << 0)
-#define NETWORK_HAS_OFDM (1 << 1)
-#define NETWORK_HAS_CCK (1 << 2)
-
-struct ieee80211_wmm_ac_param {
- u8 ac_aci_acm_aifsn;
- u8 ac_ecwmin_ecwmax;
- u16 ac_txop_limit;
-};
-
-struct ieee80211_wmm_ts_info {
- u8 ac_dir_tid;
- u8 ac_up_psb;
- u8 reserved;
-} __attribute__ ((packed));
-
-struct ieee80211_wmm_tspec_elem {
- struct ieee80211_wmm_ts_info ts_info;
- u16 norm_msdu_size;
- u16 max_msdu_size;
- u32 min_serv_inter;
- u32 max_serv_inter;
- u32 inact_inter;
- u32 suspen_inter;
- u32 serv_start_time;
- u32 min_data_rate;
- u32 mean_data_rate;
- u32 peak_data_rate;
- u32 max_burst_size;
- u32 delay_bound;
- u32 min_phy_rate;
- u16 surp_band_allow;
- u16 medium_time;
-}__attribute__((packed));
-
-enum eap_type {
- EAP_PACKET = 0,
- EAPOL_START,
- EAPOL_LOGOFF,
- EAPOL_KEY,
- EAPOL_ENCAP_ASF_ALERT
-};
-
-static const char *eap_types[] = {
- [EAP_PACKET] = "EAP-Packet",
- [EAPOL_START] = "EAPOL-Start",
- [EAPOL_LOGOFF] = "EAPOL-Logoff",
- [EAPOL_KEY] = "EAPOL-Key",
- [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
-};
-
-static inline const char *eap_get_type(int type)
-{
- return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
-}
-
-struct eapol {
- u8 snap[6];
- u16 ethertype;
- u8 version;
- u8 type;
- u16 length;
-} __attribute__ ((packed));
-
-struct ieee80211_softmac_stats {
- unsigned int rx_ass_ok;
- unsigned int rx_ass_err;
- unsigned int rx_probe_rq;
- unsigned int tx_probe_rs;
- unsigned int tx_beacons;
- unsigned int rx_auth_rq;
- unsigned int rx_auth_rs_ok;
- unsigned int rx_auth_rs_err;
- unsigned int tx_auth_rq;
- unsigned int no_auth_rs;
- unsigned int no_ass_rs;
- unsigned int tx_ass_rq;
- unsigned int rx_ass_rq;
- unsigned int tx_probe_rq;
- unsigned int reassoc;
- unsigned int swtxstop;
- unsigned int swtxawake;
-};
-
-#define BEACON_PROBE_SSID_ID_POSITION 12
-
-/*
- * 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;
- } __attribute__ ((packed));
- u32 time_stamp[2];
- u16 reason;
- u16 status;
-*/
-
-#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
-#define IEEE80211_DEFAULT_BASIC_RATE 10
-
-enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
-#define MAX_SP_Len (WMM_all_frame << 4)
-#define IEEE80211_QOS_TID 0x0f
-#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
-
-#define MAX_IE_LEN 0xFF //+YJ,080625
-
-struct rtl8187se_channel_list {
- u8 channel[MAX_CHANNEL_NUMBER + 1];
- u8 len;
-};
-
-//by amy for ps
-#define IEEE80211_WATCH_DOG_TIME 2000
-//by amy for ps
-//by amy for antenna
-#define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 // 1000 m
-//by amy for antenna
-
-#define IEEE80211_DTIM_MBCAST 4
-#define IEEE80211_DTIM_UCAST 2
-#define IEEE80211_DTIM_VALID 1
-#define IEEE80211_DTIM_INVALID 0
-
-#define IEEE80211_PS_DISABLED 0
-#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
-#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
-#define IEEE80211_PS_ENABLE IEEE80211_DTIM_VALID
-//added by David for QoS 2006/6/30
-//#define WMM_Hang_8187
-#ifdef WMM_Hang_8187
-#undef WMM_Hang_8187
-#endif
-
-#define WME_AC_BE 0x00
-#define WME_AC_BK 0x01
-#define WME_AC_VI 0x02
-#define WME_AC_VO 0x03
-#define WME_ACI_MASK 0x03
-#define WME_AIFSN_MASK 0x03
-#define WME_AC_PRAM_LEN 16
-
-//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
-//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1))
-#define UP2AC(up) ( \
- ((up) < 1) ? WME_AC_BE : \
- ((up) < 3) ? WME_AC_BK : \
- ((up) < 4) ? WME_AC_BE : \
- ((up) < 6) ? WME_AC_VI : \
- WME_AC_VO)
-//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
-#define AC2UP(_ac) ( \
- ((_ac) == WME_AC_VO) ? 6 : \
- ((_ac) == WME_AC_VI) ? 5 : \
- ((_ac) == WME_AC_BK) ? 1 : \
- 0)
-
-#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
-struct ether_header {
- u8 ether_dhost[ETHER_ADDR_LEN];
- u8 ether_shost[ETHER_ADDR_LEN];
- u16 ether_type;
-} __attribute__((packed));
-
-#ifndef ETHERTYPE_PAE
-#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
-#endif
-#ifndef ETHERTYPE_IP
-#define ETHERTYPE_IP 0x0800 /* IP protocol */
-#endif
-
-struct ieee80211_network {
- /* These entries are used to identify a unique network */
- u8 bssid[ETH_ALEN];
- u8 channel;
- /* Ensure null-terminated for any debug msgs */
- u8 ssid[IW_ESSID_MAX_SIZE + 1];
- u8 ssid_len;
-
- /* These are network statistics */
- struct ieee80211_rx_stats stats;
- u16 capability;
- u8 rates[MAX_RATES_LENGTH];
- u8 rates_len;
- u8 rates_ex[MAX_RATES_EX_LENGTH];
- u8 rates_ex_len;
- unsigned long last_scanned;
- u8 mode;
- u8 flags;
- u32 last_associate;
- u32 time_stamp[2];
- u16 beacon_interval;
- u16 listen_interval;
- u16 atim_window;
- u8 wpa_ie[MAX_WPA_IE_LEN];
- size_t wpa_ie_len;
- u8 rsn_ie[MAX_WPA_IE_LEN];
- size_t rsn_ie_len;
- u8 dtim_period;
- u8 dtim_data;
- u32 last_dtim_sta_time[2];
- struct list_head list;
- //appeded for QoS
- u8 wmm_info;
- struct ieee80211_wmm_ac_param wmm_param[4];
- u8 QoS_Enable;
- u8 SignalStrength;
-//by amy 080312
- u8 HighestOperaRate;
-//by amy 080312
- u8 Turbo_Enable;//enable turbo mode, added by thomas
- u16 CountryIeLen;
- u8 CountryIeBuf[MAX_IE_LEN];
-};
-
-enum ieee80211_state {
-
- /* the card is not linked at all */
- IEEE80211_NOLINK = 0,
-
- /* IEEE80211_ASSOCIATING* are for BSS client mode
- * the driver shall not perform RX filtering unless
- * the state is LINKED.
- * The driver shall just check for the state LINKED and
- * defaults to NOLINK for ALL the other states (including
- * LINKED_SCANNING)
- */
-
- /* the association procedure will start (wq scheduling)*/
- IEEE80211_ASSOCIATING,
- IEEE80211_ASSOCIATING_RETRY,
-
- /* the association procedure is sending AUTH request*/
- IEEE80211_ASSOCIATING_AUTHENTICATING,
-
- /* the association procedure has successfully authenticated
- * and is sending association request
- */
- IEEE80211_ASSOCIATING_AUTHENTICATED,
-
- /* the link is ok. the card associated to a BSS or linked
- * to a ibss cell or acting as an AP and creating the bss
- */
- IEEE80211_LINKED,
-
- /* same as LINKED, but the driver shall apply RX filter
- * rules as we are in NO_LINK mode. As the card is still
- * logically linked, but it is doing a syncro site survey
- * then it will be back to LINKED state.
- */
- IEEE80211_LINKED_SCANNING,
-
-};
-
-#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
-#define DEFAULT_FTS 2346
-
-#define CFG_IEEE80211_RESERVE_FCS (1<<0)
-#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
-
-typedef struct tx_pending_t{
- int frag;
- struct ieee80211_txb *txb;
-}tx_pending_t;
-
-enum {
- COUNTRY_CODE_FCC = 0,
- COUNTRY_CODE_IC = 1,
- COUNTRY_CODE_ETSI = 2,
- COUNTRY_CODE_SPAIN = 3,
- COUNTRY_CODE_FRANCE = 4,
- COUNTRY_CODE_MKK = 5,
- COUNTRY_CODE_MKK1 = 6,
- COUNTRY_CODE_ISRAEL = 7,
- COUNTRY_CODE_TELEC = 8,
- COUNTRY_CODE_GLOBAL_DOMAIN = 9,
- COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
-};
-
-struct ieee80211_device {
- struct net_device *dev;
-
- /* Bookkeeping structures */
- struct net_device_stats stats;
- struct ieee80211_stats ieee_stats;
- struct ieee80211_softmac_stats softmac_stats;
-
- /* Probe / Beacon management */
- struct list_head network_free_list;
- struct list_head network_list;
- struct ieee80211_network *networks;
- int scans;
- int scan_age;
-
- int iw_mode; /* operating mode (IW_MODE_*) */
-
- spinlock_t lock;
- spinlock_t wpax_suitlist_lock;
-
- int tx_headroom; /* Set to size of any additional room needed at front
- * of allocated Tx SKBs */
- u32 config;
-
- /* WEP and other encryption related settings at the device level */
- int open_wep; /* Set to 1 to allow unencrypted frames */
-
- int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
- * WEP key changes */
-
- /* If the host performs {en,de}cryption, then set to 1 */
- int host_encrypt;
- int host_decrypt;
- int ieee802_1x; /* is IEEE 802.1X used */
-
- /* WPA data */
- int wpa_enabled;
- int drop_unencrypted;
- int tkip_countermeasures;
- int privacy_invoked;
- size_t wpa_ie_len;
- u8 *wpa_ie;
-
- u8 ap_mac_addr[6];
- u16 pairwise_key_type;
- u16 broadcast_key_type;
-
- struct list_head crypt_deinit_list;
- struct ieee80211_crypt_data *crypt[WEP_KEYS];
- int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
- struct timer_list crypt_deinit_timer;
-
- int bcrx_sta_key; /* use individual keys to override default keys even
- * with RX of broad/multicast frames */
-
- /* Fragmentation structures */
- /* each stream contains an entry */
- struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
- unsigned int frag_next_idx[17];
- u16 fts; /* Fragmentation Threshold */
-
- /* This stores infos for the current network.
- * Either the network we are associated in INFRASTRUCTURE
- * or the network that we are creating in MASTER mode.
- * ad-hoc is a mixture ;-).
- * Note that in infrastructure mode, even when not associated,
- * fields bssid and essid may be valid (if wpa_set and essid_set
- * are true) as thy carry the value set by the user via iwconfig
- */
- struct ieee80211_network current_network;
-
-
- enum ieee80211_state state;
-
- int short_slot;
- int mode; /* A, B, G */
- int modulation; /* CCK, OFDM */
- int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
- int abg_true; /* ABG flag */
-
- /* used for forcing the ibss workqueue to terminate
- * without wait for the syncro scan to terminate
- */
- short sync_scan_hurryup;
-
- void * pDot11dInfo;
- bool bGlobalDomain;
-
- // For Liteon Ch12~13 passive scan
- u8 MinPassiveChnlNum;
- u8 IbssStartChnl;
-
- int rate; /* current rate */
- int basic_rate;
- //FIXME: please callback, see if redundant with softmac_features
- short active_scan;
-
- /* this contains flags for selectively enable softmac support */
- u16 softmac_features;
-
- /* if the sequence control field is not filled by HW */
- u16 seq_ctrl[5];
-
- /* association procedure transaction sequence number */
- u16 associate_seq;
-
- /* AID for RTXed association responses */
- u16 assoc_id;
-
- /* power save mode related*/
- short ps;
- short sta_sleep;
- int ps_timeout;
- struct tasklet_struct ps_task;
- u32 ps_th;
- u32 ps_tl;
-
- short raw_tx;
- /* used if IEEE_SOFTMAC_TX_QUEUE is set */
- short queue_stop;
- short scanning;
- short proto_started;
-
- struct semaphore wx_sem;
- struct semaphore scan_sem;
-
- spinlock_t mgmt_tx_lock;
- spinlock_t beacon_lock;
-
- short beacon_txing;
-
- short wap_set;
- short ssid_set;
-
- u8 wpax_type_set; //{added by David, 2006.9.28}
- u32 wpax_type_notify; //{added by David, 2006.9.26}
-
- /* QoS related flag */
- char init_wmmparam_flag;
-
- /* for discarding duplicated packets in IBSS */
- struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
-
- /* for discarding duplicated packets in BSS */
- u16 last_rxseq_num[17]; /* rx seq previous per-tid */
- u16 last_rxfrag_num[17];/* tx frag previous per-tid */
- unsigned long last_packet_time[17];
-
- /* for PS mode */
- unsigned long last_rx_ps_time;
-
- /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
- struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
- int mgmt_queue_head;
- int mgmt_queue_tail;
-
-
- /* used if IEEE_SOFTMAC_TX_QUEUE is set */
- struct tx_pending_t tx_pending;
-
- /* used if IEEE_SOFTMAC_ASSOCIATE is set */
- struct timer_list associate_timer;
-
- /* used if IEEE_SOFTMAC_BEACONS is set */
- struct timer_list beacon_timer;
-
- struct work_struct associate_complete_wq;
-// struct work_struct associate_retry_wq;
- struct work_struct associate_procedure_wq;
-// struct work_struct softmac_scan_wq;
- struct work_struct wx_sync_scan_wq;
- struct work_struct wmm_param_update_wq;
- struct work_struct ps_request_tx_ack_wq;//for ps
-// struct work_struct hw_wakeup_wq;
-// struct work_struct hw_sleep_wq;
-// struct work_struct watch_dog_wq;
- bool bInactivePs;
- bool actscanning;
- bool beinretry;
- u16 ListenInterval;
- unsigned long NumRxDataInPeriod; //YJ,add,080828
- unsigned long NumRxBcnInPeriod; //YJ,add,080828
- unsigned long NumRxOkTotal;
- unsigned long NumRxUnicast;//YJ,add,080828,for keep alive
- bool bHwRadioOff;
- struct delayed_work softmac_scan_wq;
- struct delayed_work associate_retry_wq;
- struct delayed_work hw_wakeup_wq;
- struct delayed_work hw_sleep_wq;//+by amy 080324
- struct delayed_work watch_dog_wq;
- struct delayed_work sw_antenna_wq;
- struct delayed_work start_ibss_wq;
-//by amy for rate adaptive 080312
- struct delayed_work rate_adapter_wq;
-//by amy for rate adaptive
- struct delayed_work hw_dig_wq;
- struct delayed_work tx_pw_wq;
-
-//Added for RF power on power off by lizhaoming 080512
- struct delayed_work GPIOChangeRFWorkItem;
-
- struct workqueue_struct *wq;
-
- /* Callback functions */
- void (*set_security)(struct net_device *dev,
- struct ieee80211_security *sec);
-
- /* Used to TX data frame by using txb structs.
- * this is not used if in the softmac_features
- * is set the flag IEEE_SOFTMAC_TX_QUEUE
- */
- int (*hard_start_xmit)(struct ieee80211_txb *txb,
- struct net_device *dev);
-
- int (*reset_port)(struct net_device *dev);
-
- /* Softmac-generated frames (management) are TXed via this
- * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
- * not set. As some cards may have different HW queues that
- * one might want to use for data and management frames
- * the option to have two callbacks might be useful.
- * This function can't sleep.
- */
- int (*softmac_hard_start_xmit)(struct sk_buff *skb,
- struct net_device *dev);
-
- /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
- * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
- * frames. If the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
- * then also management frames are sent via this callback.
- * This function can't sleep.
- */
- void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
- struct net_device *dev,int rate);
-
- /* stops the HW queue for DATA frames. Useful to avoid
- * waste time to TX data frame when we are reassociating
- * This function can sleep.
- */
- void (*data_hard_stop)(struct net_device *dev);
-
- /* OK this is complementar to data_poll_hard_stop */
- void (*data_hard_resume)(struct net_device *dev);
-
- /* ask to the driver to retune the radio .
- * This function can sleep. the driver should ensure
- * the radio has been switched before return.
- */
- void (*set_chan)(struct net_device *dev,short ch);
-
- /* These are not used if the ieee stack takes care of
- * scanning (IEEE_SOFTMAC_SCAN feature set).
- * In this case only the set_chan is used.
- *
- * The syncro version is similar to the start_scan but
- * does not return until all channels has been scanned.
- * this is called in user context and should sleep,
- * it is called in a work_queue when switching to ad-hoc mode
- * or in behalf of iwlist scan when the card is associated
- * and root user ask for a scan.
- * the function stop_scan should stop both the syncro and
- * background scanning and can sleep.
- * The function start_scan should initiate the background
- * scanning and can't sleep.
- */
- void (*scan_syncro)(struct net_device *dev);
- void (*start_scan)(struct net_device *dev);
- void (*stop_scan)(struct net_device *dev);
-
- /* indicate the driver that the link state is changed
- * for example it may indicate the card is associated now.
- * Driver might be interested in this to apply RX filter
- * rules or simply light the LINK led
- */
- void (*link_change)(struct net_device *dev);
-
- /* these two function indicates to the HW when to start
- * and stop to send beacons. This is used when the
- * IEEE_SOFTMAC_BEACONS is not set. For now the
- * stop_send_bacons is NOT guaranteed to be called only
- * after start_send_beacons.
- */
- void (*start_send_beacons) (struct net_device *dev);
- void (*stop_send_beacons) (struct net_device *dev);
-
- /* power save mode related */
- void (*sta_wake_up) (struct net_device *dev);
- void (*ps_request_tx_ack) (struct net_device *dev);
- void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
- short (*ps_is_queue_empty) (struct net_device *dev);
-
- /* QoS related */
- //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
- //void (*wmm_param_update) (struct ieee80211_device *ieee);
-
- /* This must be the last item so that it points to the data
- * allocated beyond this structure by alloc_ieee80211 */
- u8 priv[0];
-};
-
-#define IEEE_A (1<<0)
-#define IEEE_B (1<<1)
-#define IEEE_G (1<<2)
-#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
-
-/* Generate a 802.11 header */
-
-/* Uses the channel change callback directly
- * instead of [start/stop] scan callbacks
- */
-#define IEEE_SOFTMAC_SCAN (1<<2)
-
-/* Perform authentication and association handshake */
-#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
-
-/* Generate probe requests */
-#define IEEE_SOFTMAC_PROBERQ (1<<4)
-
-/* Generate response to probe requests */
-#define IEEE_SOFTMAC_PROBERS (1<<5)
-
-/* The ieee802.11 stack will manages the netif queue
- * wake/stop for the driver, taking care of 802.11
- * fragmentation. See softmac.c for details. */
-#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
-
-/* Uses only the softmac_data_hard_start_xmit
- * even for TX management frames.
- */
-#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
-
-/* Generate beacons. The stack will enqueue beacons
- * to the card
- */
-#define IEEE_SOFTMAC_BEACONS (1<<6)
-
-
-
-static inline void *ieee80211_priv(struct net_device *dev)
-{
- return ((struct ieee80211_device *)netdev_priv(dev))->priv;
-}
-
-static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
-{
- /* Single white space is for Linksys APs */
- if (essid_len == 1 && essid[0] == ' ')
- return 1;
-
- /* Otherwise, if the entire essid is 0, we assume it is hidden */
- while (essid_len) {
- essid_len--;
- if (essid[essid_len] != '\0')
- return 0;
- }
-
- return 1;
-}
-
-static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee,
- int mode)
-{
- /*
- * It is possible for both access points and our device to support
- * combinations of modes, so as long as there is one valid combination
- * of ap/device supported modes, then return success
- *
- */
- if ((mode & IEEE_A) &&
- (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
- (ieee->freq_band & IEEE80211_52GHZ_BAND))
- return 1;
-
- if ((mode & IEEE_G) &&
- (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
- (ieee->freq_band & IEEE80211_24GHZ_BAND))
- return 1;
-
- if ((mode & IEEE_B) &&
- (ieee->modulation & IEEE80211_CCK_MODULATION) &&
- (ieee->freq_band & IEEE80211_24GHZ_BAND))
- return 1;
-
- return 0;
-}
-
-static inline int ieee80211_get_hdrlen(u16 fc)
-{
- int hdrlen = 24;
-
- switch (WLAN_FC_GET_TYPE(fc)) {
- case IEEE80211_FTYPE_DATA:
- if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
- hdrlen = 30; /* Addr4 */
- if(IEEE80211_QOS_HAS_SEQ(fc))
- hdrlen += 2; /* QOS ctrl*/
- break;
- case IEEE80211_FTYPE_CTL:
- switch (WLAN_FC_GET_STYPE(fc)) {
- case IEEE80211_STYPE_CTS:
- case IEEE80211_STYPE_ACK:
- hdrlen = 10;
- break;
- default:
- hdrlen = 16;
- break;
- }
- break;
- }
-
- return hdrlen;
-}
-
-
-
-/* ieee80211.c */
-extern void free_ieee80211(struct net_device *dev);
-extern struct net_device *alloc_ieee80211(int sizeof_priv);
-
-extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
-
-/* ieee80211_tx.c */
-
-extern int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
- struct sk_buff *frag, int hdr_len);
-
-extern int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev);
-extern void ieee80211_txb_free(struct ieee80211_txb *);
-
-
-/* ieee80211_rx.c */
-extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats);
-extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *header,
- struct ieee80211_rx_stats *stats);
-
-/* ieee80211_wx.c */
-extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- struct iw_param *data, char *extra);
-int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
-/* ieee80211_softmac.c */
-extern short ieee80211_is_54g(const struct ieee80211_network *net);
-extern short ieee80211_is_shortslot(const struct ieee80211_network *net);
-extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee,
- struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats,
- u16 type, u16 stype);
-extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee,
- struct ieee80211_network *net);
-
-extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb,
- struct ieee80211_device *ieee);
-extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
-extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
-extern void ieee80211_disassociate(struct ieee80211_device *ieee);
-extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
-extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
-extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
-extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
-extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
-extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
-extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
-extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee,
- struct iw_point *p);
-extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
-extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
-extern void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta,
- u8 asRsn);
-extern void ieee80211_rtl_start_scan(struct ieee80211_device *ieee);
-
-//Add for RF power on power off by lizhaoming 080512
-extern void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta,
- u8 asRsn);
-
-/* ieee80211_crypt_ccmp&tkip&wep.c */
-extern void ieee80211_tkip_null(void);
-extern void ieee80211_wep_null(void);
-extern void ieee80211_ccmp_null(void);
-/* ieee80211_softmac_wx.c */
-
-extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *ext);
-
-extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *awrq,
- char *extra);
-
-extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
-
-extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee);
-
-extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
- short pwr);
-
-extern const long ieee80211_wlan_frequencies[];
-
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
-{
- ieee->scans++;
-}
-
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
-{
- return ieee->scans;
-}
-
-static inline const char *escape_essid(const char *essid, u8 essid_len) {
- static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
- const char *s = essid;
- char *d = escaped;
-
- if (ieee80211_is_empty_essid(essid, essid_len)) {
- memcpy(escaped, "<hidden>", sizeof("<hidden>"));
- return escaped;
- }
-
- essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
- while (essid_len--) {
- if (*s == '\0') {
- *d++ = '\\';
- *d++ = '0';
- s++;
- } else {
- *d++ = *s++;
- }
- }
- *d = '\0';
- return escaped;
-}
-#endif /* IEEE80211_H */
+++ /dev/null
-/*
- * Host AP crypto routines
- *
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.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. See README and COPYING for
- * more details.
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-//#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-
-#include "ieee80211.h"
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("HostAP crypto");
-MODULE_LICENSE("GPL");
-
-struct ieee80211_crypto_alg {
- struct list_head list;
- struct ieee80211_crypto_ops *ops;
-};
-
-
-struct ieee80211_crypto {
- struct list_head algs;
- spinlock_t lock;
-};
-
-static struct ieee80211_crypto *hcrypt;
-
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
-{
- struct list_head *ptr, *n;
- struct ieee80211_crypt_data *entry;
-
- for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
- ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
- entry = list_entry(ptr, struct ieee80211_crypt_data, list);
-
- if (atomic_read(&entry->refcnt) != 0 && !force)
- continue;
-
- list_del(ptr);
-
- if (entry->ops)
- entry->ops->deinit(entry->priv);
- kfree(entry);
- }
-}
-
-void ieee80211_crypt_deinit_handler(unsigned long data)
-{
- struct ieee80211_device *ieee = (struct ieee80211_device *)data;
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->lock, flags);
- ieee80211_crypt_deinit_entries(ieee, 0);
- if (!list_empty(&ieee->crypt_deinit_list)) {
- pr_debug("entries remaining in delayed crypt deletion list\n");
- ieee->crypt_deinit_timer.expires = jiffies + HZ;
- add_timer(&ieee->crypt_deinit_timer);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-
-}
-
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
- struct ieee80211_crypt_data **crypt)
-{
- struct ieee80211_crypt_data *tmp;
- unsigned long flags;
-
- if (*crypt == NULL)
- return;
-
- tmp = *crypt;
- *crypt = NULL;
-
- /* must not run ops->deinit() while there may be pending encrypt or
- * decrypt operations. Use a list of delayed deinits to avoid needing
- * locking. */
-
- spin_lock_irqsave(&ieee->lock, flags);
- list_add(&tmp->list, &ieee->crypt_deinit_list);
- if (!timer_pending(&ieee->crypt_deinit_timer)) {
- ieee->crypt_deinit_timer.expires = jiffies + HZ;
- add_timer(&ieee->crypt_deinit_timer);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
-{
- unsigned long flags;
- struct ieee80211_crypto_alg *alg;
-
- if (hcrypt == NULL)
- return -1;
-
- alg = kzalloc(sizeof(*alg), GFP_KERNEL);
- if (alg == NULL)
- return -ENOMEM;
-
- alg->ops = ops;
-
- spin_lock_irqsave(&hcrypt->lock, flags);
- list_add(&alg->list, &hcrypt->algs);
- spin_unlock_irqrestore(&hcrypt->lock, flags);
-
- pr_debug("registered algorithm '%s'\n", ops->name);
-
- return 0;
-}
-
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
-{
- unsigned long flags;
- struct list_head *ptr;
- struct ieee80211_crypto_alg *del_alg = NULL;
-
- if (hcrypt == NULL)
- return -1;
-
- spin_lock_irqsave(&hcrypt->lock, flags);
- for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
- struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *) ptr;
- if (alg->ops == ops) {
- list_del(&alg->list);
- del_alg = alg;
- break;
- }
- }
- spin_unlock_irqrestore(&hcrypt->lock, flags);
-
- if (del_alg) {
- pr_debug("unregistered algorithm '%s'\n", ops->name);
- kfree(del_alg);
- }
-
- return del_alg ? 0 : -1;
-}
-
-
-struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
-{
- unsigned long flags;
- struct list_head *ptr;
- struct ieee80211_crypto_alg *found_alg = NULL;
-
- if (hcrypt == NULL)
- return NULL;
-
- spin_lock_irqsave(&hcrypt->lock, flags);
- for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
- struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *) ptr;
- if (strcmp(alg->ops->name, name) == 0) {
- found_alg = alg;
- break;
- }
- }
- spin_unlock_irqrestore(&hcrypt->lock, flags);
-
- if (found_alg)
- return found_alg->ops;
- else
- return NULL;
-}
-
-
-static void *ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
-static void ieee80211_crypt_null_deinit(void *priv) {}
-
-static struct ieee80211_crypto_ops ieee80211_crypt_null = {
- .name = "NULL",
- .init = ieee80211_crypt_null_init,
- .deinit = ieee80211_crypt_null_deinit,
- .encrypt_mpdu = NULL,
- .decrypt_mpdu = NULL,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = NULL,
- .get_key = NULL,
- .extra_prefix_len = 0,
- .extra_postfix_len = 0,
- .owner = THIS_MODULE,
-};
-
-
-int ieee80211_crypto_init(void)
-{
- int ret = -ENOMEM;
-
- hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL);
- if (!hcrypt)
- goto out;
-
- INIT_LIST_HEAD(&hcrypt->algs);
- spin_lock_init(&hcrypt->lock);
-
- ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
- if (ret < 0) {
- kfree(hcrypt);
- hcrypt = NULL;
- }
-out:
- return ret;
-}
-
-
-void ieee80211_crypto_deinit(void)
-{
- struct list_head *ptr, *n;
- struct ieee80211_crypto_alg *alg = NULL;
-
- if (hcrypt == NULL)
- return;
-
- list_for_each_safe(ptr, n, &hcrypt->algs) {
- alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
- if (alg) {
- list_del(ptr);
- pr_debug("unregistered algorithm '%s' (deinit)\n",
- alg->ops->name);
- kfree(alg);
- }
- }
- kfree(hcrypt);
-}
+++ /dev/null
-/*
- * Original code based on Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- *
- * Copyright (c) 2004, Intel Corporation
- *
- * 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. See README and COPYING for
- * more details.
- */
-
-/*
- * This file defines the interface to the ieee80211 crypto module.
- */
-#ifndef IEEE80211_CRYPT_H
-#define IEEE80211_CRYPT_H
-
-#include <linux/skbuff.h>
-
-struct ieee80211_crypto_ops {
- const char *name;
-
- /* init new crypto context (e.g., allocate private data space,
- * select IV, etc.); returns NULL on failure or pointer to allocated
- * private data on success */
- void * (*init)(int keyidx);
-
- /* deinitialize crypto context and free allocated private data */
- void (*deinit)(void *priv);
-
- /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
- * value from decrypt_mpdu is passed as the keyidx value for
- * decrypt_msdu. skb must have enough head and tail room for the
- * encryption; if not, error will be returned; these functions are
- * called for all MPDUs (i.e., fragments).
- */
- int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
- int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-
- /* These functions are called for full MSDUs, i.e. full frames.
- * These can be NULL if full MSDU operations are not needed. */
- int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
- int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
- void *priv);
-
- int (*set_key)(void *key, int len, u8 *seq, void *priv);
- int (*get_key)(void *key, int len, u8 *seq, void *priv);
-
- /* procfs handler for printing out key information and possible
- * statistics */
- char * (*print_stats)(char *p, void *priv);
-
- /* maximum number of bytes added by encryption; encrypt buf is
- * allocated with extra_prefix_len bytes, copy of in_buf, and
- * extra_postfix_len; encrypt need not use all this space, but
- * the result must start at the beginning of the buffer and correct
- * length must be returned */
- int extra_prefix_len, extra_postfix_len;
-
- struct module *owner;
-};
-
-struct ieee80211_crypt_data {
- struct list_head list; /* delayed deletion list */
- struct ieee80211_crypto_ops *ops;
- void *priv;
- atomic_t refcnt;
-};
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
-struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
-void ieee80211_crypt_deinit_handler(unsigned long);
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
- struct ieee80211_crypt_data **crypt);
-
-#endif
+++ /dev/null
-/*
- * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
- *
- * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * 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. See README and COPYING for
- * more details.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <linux/string.h>
-#include <linux/wireless.h>
-
-#include "ieee80211.h"
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: CCMP");
-MODULE_LICENSE("GPL");
-
-
-#define AES_BLOCK_LEN 16
-#define CCMP_HDR_LEN 8
-#define CCMP_MIC_LEN 8
-#define CCMP_TK_LEN 16
-#define CCMP_PN_LEN 6
-
-struct ieee80211_ccmp_data {
- u8 key[CCMP_TK_LEN];
- int key_set;
-
- u8 tx_pn[CCMP_PN_LEN];
- u8 rx_pn[CCMP_PN_LEN];
-
- u32 dot11RSNAStatsCCMPFormatErrors;
- u32 dot11RSNAStatsCCMPReplays;
- u32 dot11RSNAStatsCCMPDecryptErrors;
-
- int key_idx;
-
- struct crypto_tfm *tfm;
-
- /* scratch buffers for virt_to_page() (crypto API) */
- u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
- tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
- u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
-};
-
-static void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
- const u8 pt[16], u8 ct[16])
-{
- crypto_cipher_encrypt_one((void *)tfm, ct, pt);
-}
-
-static void *ieee80211_ccmp_init(int key_idx)
-{
- struct ieee80211_ccmp_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (priv == NULL)
- goto fail;
- priv->key_idx = key_idx;
-
- priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tfm)) {
- pr_debug("could not allocate crypto API aes\n");
- priv->tfm = NULL;
- goto fail;
- }
-
- return priv;
-
-fail:
- if (priv) {
- if (priv->tfm)
- crypto_free_cipher((void *)priv->tfm);
- kfree(priv);
- }
-
- return NULL;
-}
-
-
-static void ieee80211_ccmp_deinit(void *priv)
-{
- struct ieee80211_ccmp_data *_priv = priv;
-
- if (_priv && _priv->tfm)
- crypto_free_cipher((void *)_priv->tfm);
- kfree(priv);
-}
-
-
-static inline void xor_block(u8 *b, u8 *a, size_t len)
-{
- int i;
- for (i = 0; i < len; i++)
- b[i] ^= a[i];
-}
-
-static void ccmp_init_blocks(struct crypto_tfm *tfm,
- struct ieee80211_hdr_4addr *hdr,
- u8 *pn, size_t dlen, u8 *b0, u8 *auth,
- u8 *s0)
-{
- u8 *pos, qc = 0;
- size_t aad_len;
- u16 fc;
- int a4_included, qc_included;
- u8 aad[2 * AES_BLOCK_LEN];
-
- fc = le16_to_cpu(hdr->frame_ctl);
- a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
- /*
- qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
- (WLAN_FC_GET_STYPE(fc) & 0x08));
- */
- qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
- (WLAN_FC_GET_STYPE(fc) & 0x80));
- aad_len = 22;
- if (a4_included)
- aad_len += 6;
- if (qc_included) {
- pos = (u8 *) &hdr->addr4;
- if (a4_included)
- pos += 6;
- qc = *pos & 0x0f;
- aad_len += 2;
- }
- /* CCM Initial Block:
- * Flag (Include authentication header, M=3 (8-octet MIC),
- * L=1 (2-octet Dlen))
- * Nonce: 0x00 | A2 | PN
- * Dlen */
- b0[0] = 0x59;
- b0[1] = qc;
- memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
- memcpy(b0 + 8, pn, CCMP_PN_LEN);
- b0[14] = (dlen >> 8) & 0xff;
- b0[15] = dlen & 0xff;
-
- /* AAD:
- * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
- * A1 | A2 | A3
- * SC with bits 4..15 (seq#) masked to zero
- * A4 (if present)
- * QC (if present)
- */
- pos = (u8 *) hdr;
- aad[0] = 0; /* aad_len >> 8 */
- aad[1] = aad_len & 0xff;
- aad[2] = pos[0] & 0x8f;
- aad[3] = pos[1] & 0xc7;
- memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
- pos = (u8 *) &hdr->seq_ctl;
- aad[22] = pos[0] & 0x0f;
- aad[23] = 0; /* all bits masked */
- memset(aad + 24, 0, 8);
- if (a4_included)
- memcpy(aad + 24, hdr->addr4, ETH_ALEN);
- if (qc_included) {
- aad[a4_included ? 30 : 24] = qc;
- /* rest of QC masked */
- }
-
- /* Start with the first block and AAD */
- ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
- xor_block(auth, aad, AES_BLOCK_LEN);
- ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
- xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
- ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
- b0[0] &= 0x07;
- b0[14] = b0[15] = 0;
- ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
-}
-
-static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_ccmp_data *key = priv;
- int data_len, i;
- u8 *pos;
- struct ieee80211_hdr_4addr *hdr;
- int blocks, last, len;
- u8 *mic;
- u8 *b0 = key->tx_b0;
- u8 *b = key->tx_b;
- u8 *e = key->tx_e;
- u8 *s0 = key->tx_s0;
-
- if (skb_headroom(skb) < CCMP_HDR_LEN ||
- skb_tailroom(skb) < CCMP_MIC_LEN ||
- skb->len < hdr_len)
- return -1;
-
- data_len = skb->len - hdr_len;
- pos = skb_push(skb, CCMP_HDR_LEN);
- memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
- pos += hdr_len;
-
- i = CCMP_PN_LEN - 1;
- while (i >= 0) {
- key->tx_pn[i]++;
- if (key->tx_pn[i] != 0)
- break;
- i--;
- }
-
- *pos++ = key->tx_pn[5];
- *pos++ = key->tx_pn[4];
- *pos++ = 0;
- *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
- *pos++ = key->tx_pn[3];
- *pos++ = key->tx_pn[2];
- *pos++ = key->tx_pn[1];
- *pos++ = key->tx_pn[0];
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- mic = skb_put(skb, CCMP_MIC_LEN);
-
- ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
-
- blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
- last = data_len % AES_BLOCK_LEN;
-
- for (i = 1; i <= blocks; i++) {
- len = (i == blocks && last) ? last : AES_BLOCK_LEN;
- /* Authentication */
- xor_block(b, pos, len);
- ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
- /* Encryption, with counter */
- b0[14] = (i >> 8) & 0xff;
- b0[15] = i & 0xff;
- ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
- xor_block(pos, e, len);
- pos += len;
- }
-
- for (i = 0; i < CCMP_MIC_LEN; i++)
- mic[i] = b[i] ^ s0[i];
-
- return 0;
-}
-
-
-static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_ccmp_data *key = priv;
- u8 keyidx, *pos;
- struct ieee80211_hdr_4addr *hdr;
- u8 pn[6];
- size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
- u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
- u8 *b0 = key->rx_b0;
- u8 *b = key->rx_b;
- u8 *a = key->rx_a;
- int i, blocks, last, len;
-
- if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
- key->dot11RSNAStatsCCMPFormatErrors++;
- return -1;
- }
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- pos = skb->data + hdr_len;
- keyidx = pos[3];
- if (!(keyidx & (1 << 5))) {
- if (net_ratelimit()) {
- pr_debug("received packet without ExtIV flag from %pM\n",
- hdr->addr2);
- }
- key->dot11RSNAStatsCCMPFormatErrors++;
- return -2;
- }
- keyidx >>= 6;
- if (key->key_idx != keyidx) {
- pr_debug("RX tkey->key_idx=%d frame keyidx=%d priv=%p\n",
- key->key_idx, keyidx, priv);
- return -6;
- }
- if (!key->key_set) {
- if (net_ratelimit()) {
- pr_debug("received packet from %pM with keyid=%d that does not have a configured key\n",
- hdr->addr2, keyidx);
- }
- return -3;
- }
-
- pn[0] = pos[7];
- pn[1] = pos[6];
- pn[2] = pos[5];
- pn[3] = pos[4];
- pn[4] = pos[1];
- pn[5] = pos[0];
- pos += 8;
-
- if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
- if (net_ratelimit()) {
- pr_debug("replay detected: STA=%pM previous PN %pm received PN %pm\n",
- hdr->addr2, key->rx_pn, pn);
- }
- key->dot11RSNAStatsCCMPReplays++;
- return -4;
- }
-
- ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
- xor_block(mic, b, CCMP_MIC_LEN);
-
- blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
- last = data_len % AES_BLOCK_LEN;
-
- for (i = 1; i <= blocks; i++) {
- len = (i == blocks && last) ? last : AES_BLOCK_LEN;
- /* Decrypt, with counter */
- b0[14] = (i >> 8) & 0xff;
- b0[15] = i & 0xff;
- ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
- xor_block(pos, b, len);
- /* Authentication */
- xor_block(a, pos, len);
- ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
- pos += len;
- }
-
- if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
- if (net_ratelimit())
- pr_debug("decrypt failed: STA=%pM\n", hdr->addr2);
-
- key->dot11RSNAStatsCCMPDecryptErrors++;
- return -5;
- }
-
- memcpy(key->rx_pn, pn, CCMP_PN_LEN);
-
- /* Remove hdr and MIC */
- memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
- skb_pull(skb, CCMP_HDR_LEN);
- skb_trim(skb, skb->len - CCMP_MIC_LEN);
-
- return keyidx;
-}
-
-
-static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
-{
- struct ieee80211_ccmp_data *data = priv;
- int keyidx;
- struct crypto_tfm *tfm = data->tfm;
-
- keyidx = data->key_idx;
- memset(data, 0, sizeof(*data));
- data->key_idx = keyidx;
- data->tfm = tfm;
- if (len == CCMP_TK_LEN) {
- memcpy(data->key, key, CCMP_TK_LEN);
- data->key_set = 1;
- if (seq) {
- data->rx_pn[0] = seq[5];
- data->rx_pn[1] = seq[4];
- data->rx_pn[2] = seq[3];
- data->rx_pn[3] = seq[2];
- data->rx_pn[4] = seq[1];
- data->rx_pn[5] = seq[0];
- }
- crypto_cipher_setkey((void *)data->tfm, data->key, CCMP_TK_LEN);
- } else if (len == 0)
- data->key_set = 0;
- else
- return -1;
-
- return 0;
-}
-
-
-static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
-{
- struct ieee80211_ccmp_data *data = priv;
-
- if (len < CCMP_TK_LEN)
- return -1;
-
- if (!data->key_set)
- return 0;
- memcpy(key, data->key, CCMP_TK_LEN);
-
- if (seq) {
- seq[0] = data->tx_pn[5];
- seq[1] = data->tx_pn[4];
- seq[2] = data->tx_pn[3];
- seq[3] = data->tx_pn[2];
- seq[4] = data->tx_pn[1];
- seq[5] = data->tx_pn[0];
- }
-
- return CCMP_TK_LEN;
-}
-
-
-static char *ieee80211_ccmp_print_stats(char *p, void *priv)
-{
- struct ieee80211_ccmp_data *ccmp = priv;
- p += sprintf(p,
- "key[%d] alg=CCMP key_set=%d tx_pn=%pm rx_pn=%pm format_errors=%d replays=%d decrypt_errors=%d\n",
- ccmp->key_idx, ccmp->key_set,
- ccmp->tx_pn, ccmp->rx_pn,
- ccmp->dot11RSNAStatsCCMPFormatErrors,
- ccmp->dot11RSNAStatsCCMPReplays,
- ccmp->dot11RSNAStatsCCMPDecryptErrors);
-
- return p;
-}
-
-void ieee80211_ccmp_null(void)
-{
- return;
-}
-static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
- .name = "CCMP",
- .init = ieee80211_ccmp_init,
- .deinit = ieee80211_ccmp_deinit,
- .encrypt_mpdu = ieee80211_ccmp_encrypt,
- .decrypt_mpdu = ieee80211_ccmp_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = ieee80211_ccmp_set_key,
- .get_key = ieee80211_ccmp_get_key,
- .print_stats = ieee80211_ccmp_print_stats,
- .extra_prefix_len = CCMP_HDR_LEN,
- .extra_postfix_len = CCMP_MIC_LEN,
- .owner = THIS_MODULE,
-};
-
-
-int ieee80211_crypto_ccmp_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
-}
-
-
-void ieee80211_crypto_ccmp_exit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
-}
+++ /dev/null
-/*
- * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
- *
- * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * 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. See README and COPYING for
- * more details.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <asm/string.h>
-
-#include "ieee80211.h"
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-#include <linux/crc32.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: TKIP");
-MODULE_LICENSE("GPL");
-
-
-struct ieee80211_tkip_data {
-#define TKIP_KEY_LEN 32
- u8 key[TKIP_KEY_LEN];
- int key_set;
-
- u32 tx_iv32;
- u16 tx_iv16;
- u16 tx_ttak[5];
- int tx_phase1_done;
-
- u32 rx_iv32;
- u16 rx_iv16;
- u16 rx_ttak[5];
- int rx_phase1_done;
- u32 rx_iv32_new;
- u16 rx_iv16_new;
-
- u32 dot11RSNAStatsTKIPReplays;
- u32 dot11RSNAStatsTKIPICVErrors;
- u32 dot11RSNAStatsTKIPLocalMICFailures;
-
- int key_idx;
-
- struct crypto_blkcipher *rx_tfm_arc4;
- struct crypto_hash *rx_tfm_michael;
- struct crypto_blkcipher *tx_tfm_arc4;
- struct crypto_hash *tx_tfm_michael;
- struct crypto_tfm *tfm_arc4;
- struct crypto_tfm *tfm_michael;
-
- /* scratch buffers for virt_to_page() (crypto API) */
- u8 rx_hdr[16], tx_hdr[16];
-};
-
-static void *ieee80211_tkip_init(int key_idx)
-{
- struct ieee80211_tkip_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (priv == NULL)
- goto fail;
- priv->key_idx = key_idx;
-
- priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tx_tfm_arc4)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API arc4\n");
- priv->tx_tfm_arc4 = NULL;
- goto fail;
- }
-
- priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tx_tfm_michael)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API michael_mic\n");
- priv->tx_tfm_michael = NULL;
- goto fail;
- }
-
- priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->rx_tfm_arc4)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API arc4\n");
- priv->rx_tfm_arc4 = NULL;
- goto fail;
- }
-
- priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->rx_tfm_michael)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API michael_mic\n");
- priv->rx_tfm_michael = NULL;
- goto fail;
- }
-
- return priv;
-
-fail:
- if (priv) {
- if (priv->tx_tfm_michael)
- crypto_free_hash(priv->tx_tfm_michael);
- if (priv->tx_tfm_arc4)
- crypto_free_blkcipher(priv->tx_tfm_arc4);
- if (priv->rx_tfm_michael)
- crypto_free_hash(priv->rx_tfm_michael);
- if (priv->rx_tfm_arc4)
- crypto_free_blkcipher(priv->rx_tfm_arc4);
- kfree(priv);
- }
-
- return NULL;
-}
-
-
-static void ieee80211_tkip_deinit(void *priv)
-{
- struct ieee80211_tkip_data *_priv = priv;
-
- if (_priv) {
- if (_priv->tx_tfm_michael)
- crypto_free_hash(_priv->tx_tfm_michael);
- if (_priv->tx_tfm_arc4)
- crypto_free_blkcipher(_priv->tx_tfm_arc4);
- if (_priv->rx_tfm_michael)
- crypto_free_hash(_priv->rx_tfm_michael);
- if (_priv->rx_tfm_arc4)
- crypto_free_blkcipher(_priv->rx_tfm_arc4);
- }
- kfree(priv);
-}
-
-
-static inline u16 RotR1(u16 val)
-{
- return (val >> 1) | (val << 15);
-}
-
-
-static inline u8 Lo8(u16 val)
-{
- return val & 0xff;
-}
-
-
-static inline u8 Hi8(u16 val)
-{
- return val >> 8;
-}
-
-
-static inline u16 Lo16(u32 val)
-{
- return val & 0xffff;
-}
-
-
-static inline u16 Hi16(u32 val)
-{
- return val >> 16;
-}
-
-
-static inline u16 Mk16(u8 hi, u8 lo)
-{
- return lo | (((u16) hi) << 8);
-}
-
-
-static inline u16 Mk16_le(u16 *v)
-{
- return le16_to_cpu(*v);
-}
-
-
-static const u16 Sbox[256] = {
- 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,
-};
-
-
-static inline u16 _S_(u16 v)
-{
- u16 t = Sbox[Hi8(v)];
- return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
-}
-
-#define PHASE1_LOOP_COUNT 8
-
-static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
-{
- int i, j;
-
- /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
- TTAK[0] = Lo16(IV32);
- TTAK[1] = Hi16(IV32);
- TTAK[2] = Mk16(TA[1], TA[0]);
- TTAK[3] = Mk16(TA[3], TA[2]);
- TTAK[4] = Mk16(TA[5], TA[4]);
-
- for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
- j = 2 * (i & 1);
- TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
- TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
- TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
- TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
- TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
- }
-}
-
-
-static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
- u16 IV16)
-{
- /* Make temporary area overlap WEP seed so that the final copy can be
- * avoided on little endian hosts. */
- u16 *PPK = (u16 *) &WEPSeed[4];
-
- /* Step 1 - make copy of TTAK and bring in TSC */
- PPK[0] = TTAK[0];
- PPK[1] = TTAK[1];
- PPK[2] = TTAK[2];
- PPK[3] = TTAK[3];
- PPK[4] = TTAK[4];
- PPK[5] = TTAK[4] + IV16;
-
- /* Step 2 - 96-bit bijective mixing using S-box */
- PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
- PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
- PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
- PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
- PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
- PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
-
- PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
- PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
- PPK[2] += RotR1(PPK[1]);
- PPK[3] += RotR1(PPK[2]);
- PPK[4] += RotR1(PPK[3]);
- PPK[5] += RotR1(PPK[4]);
-
- /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
- * WEPSeed[0..2] is transmitted as WEP IV */
- WEPSeed[0] = Hi8(IV16);
- WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
- WEPSeed[2] = Lo8(IV16);
- WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
-
-#ifdef __BIG_ENDIAN
- {
- int i;
- for (i = 0; i < 6; i++)
- PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
- }
-#endif
-}
-
-static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
- int len;
- u8 *pos;
- struct ieee80211_hdr_4addr *hdr;
- u8 rc4key[16], *icv;
- u32 crc;
- struct scatterlist sg;
- int ret;
-
- ret = 0;
- if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
- skb->len < hdr_len)
- return -1;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- if (!tkey->tx_phase1_done) {
- tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
- tkey->tx_iv32);
- tkey->tx_phase1_done = 1;
- }
- tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
-
- len = skb->len - hdr_len;
- pos = skb_push(skb, 8);
- memmove(pos, pos + 8, hdr_len);
- pos += hdr_len;
-
- *pos++ = rc4key[0];
- *pos++ = rc4key[1];
- *pos++ = rc4key[2];
- *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
- *pos++ = tkey->tx_iv32 & 0xff;
- *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
- *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
- *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
-
- icv = skb_put(skb, 4);
- crc = ~crc32_le(~0, pos, len);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
- crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
- sg_init_one(&sg, pos, len + 4);
- ret = crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-
- tkey->tx_iv16++;
- if (tkey->tx_iv16 == 0) {
- tkey->tx_phase1_done = 0;
- tkey->tx_iv32++;
- }
- return ret;
-}
-
-static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
- u8 keyidx, *pos;
- u32 iv32;
- u16 iv16;
- struct ieee80211_hdr_4addr *hdr;
- u8 icv[4];
- u32 crc;
- struct scatterlist sg;
- u8 rc4key[16];
- int plen;
-
- if (skb->len < hdr_len + 8 + 4)
- return -1;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- pos = skb->data + hdr_len;
- keyidx = pos[3];
- if (!(keyidx & (1 << 5))) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: received packet without ExtIV"
- " flag from %pM\n", hdr->addr2);
- }
- return -2;
- }
- keyidx >>= 6;
- if (tkey->key_idx != keyidx) {
- printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
- "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
- return -6;
- }
- if (!tkey->key_set) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: received packet from %pM"
- " with keyid=%d that does not have a configured"
- " key\n", hdr->addr2, keyidx);
- }
- return -3;
- }
- iv16 = (pos[0] << 8) | pos[2];
- iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
- pos += 8;
-
- if (iv32 < tkey->rx_iv32 ||
- (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
- " previous TSC %08x%04x received TSC "
- "%08x%04x\n", hdr->addr2,
- tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
- }
- tkey->dot11RSNAStatsTKIPReplays++;
- return -4;
- }
-
- if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
- tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
- tkey->rx_phase1_done = 1;
- }
- tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
-
- plen = skb->len - hdr_len - 12;
- crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
- sg_init_one(&sg, pos, plen + 4);
- if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG ": TKIP: failed to decrypt "
- "received packet from %pM\n",
- hdr->addr2);
- }
- return -7;
- }
-
- crc = ~crc32_le(~0, pos, plen);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
- if (memcmp(icv, pos + plen, 4) != 0) {
- if (iv32 != tkey->rx_iv32) {
- /* Previously cached Phase1 result was already lost, so
- * it needs to be recalculated for the next packet. */
- tkey->rx_phase1_done = 0;
- }
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: ICV error detected: STA="
- "%pM\n", hdr->addr2);
- }
- tkey->dot11RSNAStatsTKIPICVErrors++;
- return -5;
- }
-
- /* Update real counters only after Michael MIC verification has
- * completed */
- tkey->rx_iv32_new = iv32;
- tkey->rx_iv16_new = iv16;
-
- /* Remove IV and ICV */
- memmove(skb->data + 8, skb->data, hdr_len);
- skb_pull(skb, 8);
- skb_trim(skb, skb->len - 4);
-
- return keyidx;
-}
-
-static int michael_mic(struct crypto_hash *tfm_michael, u8 *key, u8 *hdr,
- u8 *data, size_t data_len, u8 *mic)
-{
- struct hash_desc desc;
- struct scatterlist sg[2];
-
- if (tfm_michael == NULL) {
- printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
- return -1;
- }
-
- sg_init_table(sg, 2);
- sg_set_buf(&sg[0], hdr, 16);
- sg_set_buf(&sg[1], data, data_len);
-
- if (crypto_hash_setkey(tfm_michael, key, 8))
- return -1;
-
- desc.tfm = tfm_michael;
- desc.flags = 0;
- return crypto_hash_digest(&desc, sg, data_len + 16, mic);
-}
-
-static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
-{
- struct ieee80211_hdr_4addr *hdr11;
-
- hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
- switch (le16_to_cpu(hdr11->frame_ctl) &
- (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- case IEEE80211_FCTL_TODS:
- memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- break;
- case IEEE80211_FCTL_FROMDS:
- memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
- break;
- case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
- break;
- case 0:
- memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- break;
- }
-
- hdr[12] = 0; /* priority */
-
- hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
-}
-
-
-static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
- void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- u8 *pos;
- struct ieee80211_hdr_4addr *hdr;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
- printk(KERN_DEBUG "Invalid packet for Michael MIC add "
- "(tailroom=%d hdr_len=%d skb->len=%d)\n",
- skb_tailroom(skb), hdr_len, skb->len);
- return -1;
- }
-
- michael_mic_hdr(skb, tkey->tx_hdr);
-
- if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl)))
- tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
-
- pos = skb_put(skb, 8);
-
- if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
- return -1;
-
- return 0;
-}
-
-static void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr_4addr *hdr,
- int keyidx)
-{
- union iwreq_data wrqu;
- struct iw_michaelmicfailure ev;
-
- /* TODO: needed parameters: count, keyid, key type, TSC */
- memset(&ev, 0, sizeof(ev));
- ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
- if (hdr->addr1[0] & 0x01)
- ev.flags |= IW_MICFAILURE_GROUP;
- else
- ev.flags |= IW_MICFAILURE_PAIRWISE;
- ev.src_addr.sa_family = ARPHRD_ETHER;
- memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = sizeof(ev);
- wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
-}
-
-static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
- int hdr_len, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- u8 mic[8];
- struct ieee80211_hdr_4addr *hdr;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- if (!tkey->key_set)
- return -1;
-
- michael_mic_hdr(skb, tkey->rx_hdr);
- if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl)))
- tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
-
- if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
- return -1;
-
- if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
- struct ieee80211_hdr_4addr *hdr;
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- printk(KERN_DEBUG "%s: Michael MIC verification failed for "
- "MSDU from %pM keyidx=%d\n",
- skb->dev ? skb->dev->name : "N/A", hdr->addr2,
- keyidx);
- if (skb->dev)
- ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
- tkey->dot11RSNAStatsTKIPLocalMICFailures++;
- return -1;
- }
-
- /* Update TSC counters for RX now that the packet verification has
- * completed. */
- tkey->rx_iv32 = tkey->rx_iv32_new;
- tkey->rx_iv16 = tkey->rx_iv16_new;
-
- skb_trim(skb, skb->len - 8);
-
- return 0;
-}
-
-
-static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- int keyidx;
- struct crypto_hash *tfm = tkey->tx_tfm_michael;
- struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
- struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
- struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
-
- keyidx = tkey->key_idx;
- memset(tkey, 0, sizeof(*tkey));
- tkey->key_idx = keyidx;
-
- tkey->tx_tfm_michael = tfm;
- tkey->tx_tfm_arc4 = tfm2;
- tkey->rx_tfm_michael = tfm3;
- tkey->rx_tfm_arc4 = tfm4;
-
- if (len == TKIP_KEY_LEN) {
- memcpy(tkey->key, key, TKIP_KEY_LEN);
- tkey->key_set = 1;
- tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
- if (seq) {
- tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
- (seq[3] << 8) | seq[2];
- tkey->rx_iv16 = (seq[1] << 8) | seq[0];
- }
- } else if (len == 0)
- tkey->key_set = 0;
- else
- return -1;
-
- return 0;
-}
-
-
-static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
-
- if (len < TKIP_KEY_LEN)
- return -1;
-
- if (!tkey->key_set)
- return 0;
- memcpy(key, tkey->key, TKIP_KEY_LEN);
-
- if (seq) {
- /* Return the sequence number of the last transmitted frame. */
- u16 iv16 = tkey->tx_iv16;
- u32 iv32 = tkey->tx_iv32;
- if (iv16 == 0)
- iv32--;
- iv16--;
- seq[0] = tkey->tx_iv16;
- seq[1] = tkey->tx_iv16 >> 8;
- seq[2] = tkey->tx_iv32;
- seq[3] = tkey->tx_iv32 >> 8;
- seq[4] = tkey->tx_iv32 >> 16;
- seq[5] = tkey->tx_iv32 >> 24;
- }
-
- return TKIP_KEY_LEN;
-}
-
-
-static char *ieee80211_tkip_print_stats(char *p, void *priv)
-{
- struct ieee80211_tkip_data *tkip = priv;
- p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
- "tx_pn=%02x%02x%02x%02x%02x%02x "
- "rx_pn=%02x%02x%02x%02x%02x%02x "
- "replays=%d icv_errors=%d local_mic_failures=%d\n",
- tkip->key_idx, tkip->key_set,
- (tkip->tx_iv32 >> 24) & 0xff,
- (tkip->tx_iv32 >> 16) & 0xff,
- (tkip->tx_iv32 >> 8) & 0xff,
- tkip->tx_iv32 & 0xff,
- (tkip->tx_iv16 >> 8) & 0xff,
- tkip->tx_iv16 & 0xff,
- (tkip->rx_iv32 >> 24) & 0xff,
- (tkip->rx_iv32 >> 16) & 0xff,
- (tkip->rx_iv32 >> 8) & 0xff,
- tkip->rx_iv32 & 0xff,
- (tkip->rx_iv16 >> 8) & 0xff,
- tkip->rx_iv16 & 0xff,
- tkip->dot11RSNAStatsTKIPReplays,
- tkip->dot11RSNAStatsTKIPICVErrors,
- tkip->dot11RSNAStatsTKIPLocalMICFailures);
- return p;
-}
-
-
-static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
- .name = "TKIP",
- .init = ieee80211_tkip_init,
- .deinit = ieee80211_tkip_deinit,
- .encrypt_mpdu = ieee80211_tkip_encrypt,
- .decrypt_mpdu = ieee80211_tkip_decrypt,
- .encrypt_msdu = ieee80211_michael_mic_add,
- .decrypt_msdu = ieee80211_michael_mic_verify,
- .set_key = ieee80211_tkip_set_key,
- .get_key = ieee80211_tkip_get_key,
- .print_stats = ieee80211_tkip_print_stats,
- .extra_prefix_len = 4 + 4, /* IV + ExtIV */
- .extra_postfix_len = 8 + 4, /* MIC + ICV */
- .owner = THIS_MODULE,
-};
-
-
-int ieee80211_crypto_tkip_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
-}
-
-
-void ieee80211_crypto_tkip_exit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
-}
-
-
-void ieee80211_tkip_null(void)
-{
-}
+++ /dev/null
-/*
- * Host AP crypt: host-based WEP encryption implementation for Host AP driver
- *
- * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * 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. See README and COPYING for
- * more details.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/string.h>
-
-#include "ieee80211.h"
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-#include <linux/crc32.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: WEP");
-MODULE_LICENSE("GPL");
-
-struct prism2_wep_data {
- u32 iv;
-#define WEP_KEY_LEN 13
- u8 key[WEP_KEY_LEN + 1];
- u8 key_len;
- u8 key_idx;
- struct crypto_blkcipher *tx_tfm;
- struct crypto_blkcipher *rx_tfm;
-};
-
-static void *prism2_wep_init(int keyidx)
-{
- struct prism2_wep_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (priv == NULL)
- goto fail;
- priv->key_idx = keyidx;
- priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tx_tfm)) {
- pr_debug("could not allocate crypto API arc4\n");
- priv->tx_tfm = NULL;
- goto fail;
- }
- priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->rx_tfm)) {
- pr_debug("could not allocate crypto API arc4\n");
- priv->rx_tfm = NULL;
- goto fail;
- }
-
- /* start WEP IV from a random value */
- get_random_bytes(&priv->iv, 4);
-
- return priv;
-
-fail:
- if (priv) {
- if (priv->tx_tfm)
- crypto_free_blkcipher(priv->tx_tfm);
- if (priv->rx_tfm)
- crypto_free_blkcipher(priv->rx_tfm);
- kfree(priv);
- }
-
- return NULL;
-}
-
-static void prism2_wep_deinit(void *priv)
-{
- struct prism2_wep_data *_priv = priv;
-
- if (_priv) {
- if (_priv->tx_tfm)
- crypto_free_blkcipher(_priv->tx_tfm);
- if (_priv->rx_tfm)
- crypto_free_blkcipher(_priv->rx_tfm);
- }
-
- kfree(priv);
-}
-
-/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
- * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
- * so the payload length increases with 8 bytes.
- *
- * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
- */
-static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
- u32 klen, len;
- u8 key[WEP_KEY_LEN + 3];
- u8 *pos;
- u32 crc;
- u8 *icv;
- struct scatterlist sg;
-
- if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
- skb->len < hdr_len)
- return -1;
-
- len = skb->len - hdr_len;
- pos = skb_push(skb, 4);
- memmove(pos, pos + 4, hdr_len);
- pos += hdr_len;
-
- klen = 3 + wep->key_len;
-
- wep->iv++;
-
- /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
- * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
- * can be used to speedup attacks, so avoid using them. */
- if ((wep->iv & 0xff00) == 0xff00) {
- u8 B = (wep->iv >> 16) & 0xff;
- if (B >= 3 && B < klen)
- wep->iv += 0x0100;
- }
-
- /* Prepend 24-bit IV to RC4 key and TX frame */
- *pos++ = key[0] = (wep->iv >> 16) & 0xff;
- *pos++ = key[1] = (wep->iv >> 8) & 0xff;
- *pos++ = key[2] = wep->iv & 0xff;
- *pos++ = wep->key_idx << 6;
-
- /* Copy rest of the WEP key (the secret part) */
- memcpy(key + 3, wep->key, wep->key_len);
-
- /* Append little-endian CRC32 and encrypt it to produce ICV */
- crc = ~crc32_le(~0, pos, len);
- icv = skb_put(skb, 4);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
-
- crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
- sg_init_one(&sg, pos, len + 4);
-
- return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-}
-
-/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
- * the frame: IV (4 bytes), encrypted payload (including SNAP header),
- * ICV (4 bytes). len includes both IV and ICV.
- *
- * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
- * failure. If frame is OK, IV and ICV will be removed.
- */
-static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
- u32 klen, plen;
- u8 key[WEP_KEY_LEN + 3];
- u8 keyidx, *pos;
- u32 crc;
- u8 icv[4];
- struct scatterlist sg;
-
- if (skb->len < hdr_len + 8)
- return -1;
-
- pos = skb->data + hdr_len;
- key[0] = *pos++;
- key[1] = *pos++;
- key[2] = *pos++;
- keyidx = *pos++ >> 6;
- if (keyidx != wep->key_idx)
- return -1;
-
- klen = 3 + wep->key_len;
-
- /* Copy rest of the WEP key (the secret part) */
- memcpy(key + 3, wep->key, wep->key_len);
-
- /* Apply RC4 to data and compute CRC32 over decrypted data */
- plen = skb->len - hdr_len - 8;
-
- crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
- sg_init_one(&sg, pos, plen + 4);
-
- if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
- return -7;
-
- crc = ~crc32_le(~0, pos, plen);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
-
- if (memcmp(icv, pos + plen, 4) != 0) {
- /* ICV mismatch - drop frame */
- return -2;
- }
-
- /* Remove IV and ICV */
- memmove(skb->data + 4, skb->data, hdr_len);
- skb_pull(skb, 4);
- skb_trim(skb, skb->len - 4);
- return 0;
-}
-
-static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
-{
- struct prism2_wep_data *wep = priv;
-
- if (len < 0 || len > WEP_KEY_LEN)
- return -1;
-
- memcpy(wep->key, key, len);
- wep->key_len = len;
-
- return 0;
-}
-
-static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
-{
- struct prism2_wep_data *wep = priv;
-
- if (len < wep->key_len)
- return -1;
-
- memcpy(key, wep->key, wep->key_len);
-
- return wep->key_len;
-}
-
-static char *prism2_wep_print_stats(char *p, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- p += sprintf(p, "key[%d] alg=WEP len=%d\n",
- wep->key_idx, wep->key_len);
- return p;
-}
-
-static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
- .name = "WEP",
- .init = prism2_wep_init,
- .deinit = prism2_wep_deinit,
- .encrypt_mpdu = prism2_wep_encrypt,
- .decrypt_mpdu = prism2_wep_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = prism2_wep_set_key,
- .get_key = prism2_wep_get_key,
- .print_stats = prism2_wep_print_stats,
- .extra_prefix_len = 4, /* IV */
- .extra_postfix_len = 4, /* ICV */
- .owner = THIS_MODULE,
-};
-
-int ieee80211_crypto_wep_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
-}
-
-void ieee80211_crypto_wep_exit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
-}
-
-void ieee80211_wep_null(void)
-{
- return;
-}
+++ /dev/null
-/*******************************************************************************
-
- Copyright(c) 2004 Intel Corporation. All rights reserved.
-
- Portions of this file are based on the WEP enablement code provided by the
- Host AP project hostap-drivers v0.1.3
- Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- <jkmaline@cc.hut.fi>
- Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
-
- 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.
-
- 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., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- 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
-
-*******************************************************************************/
-
-#include <linux/compiler.h>
-//#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <linux/uaccess.h>
-#include <net/arp.h>
-#include <net/net_namespace.h>
-
-#include "ieee80211.h"
-
-MODULE_DESCRIPTION("802.11 data/management/control stack");
-MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
-MODULE_LICENSE("GPL");
-
-#define DRV_NAME "ieee80211"
-
-static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
-{
- if (ieee->networks)
- return 0;
-
- ieee->networks = kcalloc(
- MAX_NETWORK_COUNT, sizeof(struct ieee80211_network),
- GFP_KERNEL);
- if (!ieee->networks)
- return -ENOMEM;
-
- return 0;
-}
-
-static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
-{
- if (!ieee->networks)
- return;
- kfree(ieee->networks);
- ieee->networks = NULL;
-}
-
-static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
-{
- int i;
-
- INIT_LIST_HEAD(&ieee->network_free_list);
- INIT_LIST_HEAD(&ieee->network_list);
- for (i = 0; i < MAX_NETWORK_COUNT; i++)
- list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
-}
-
-
-struct net_device *alloc_ieee80211(int sizeof_priv)
-{
- struct ieee80211_device *ieee;
- struct net_device *dev;
- int i, err;
-
- IEEE80211_DEBUG_INFO("Initializing...\n");
-
- dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
- if (!dev) {
- IEEE80211_ERROR("Unable to network device.\n");
- goto failed;
- }
- ieee = netdev_priv(dev);
-
- ieee->dev = dev;
-
- err = ieee80211_networks_allocate(ieee);
- if (err) {
- IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
- err);
- goto failed;
- }
- ieee80211_networks_initialize(ieee);
-
- /* Default fragmentation threshold is maximum payload size */
- ieee->fts = DEFAULT_FTS;
- ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
- ieee->open_wep = 1;
-
- /* Default to enabling full open WEP with host based encrypt/decrypt */
- ieee->host_encrypt = 1;
- ieee->host_decrypt = 1;
- ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
-
- INIT_LIST_HEAD(&ieee->crypt_deinit_list);
- init_timer(&ieee->crypt_deinit_timer);
- ieee->crypt_deinit_timer.data = (unsigned long)ieee;
- ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
-
- spin_lock_init(&ieee->lock);
- spin_lock_init(&ieee->wpax_suitlist_lock);
-
- ieee->wpax_type_set = 0;
- ieee->wpa_enabled = 0;
- ieee->tkip_countermeasures = 0;
- ieee->drop_unencrypted = 0;
- ieee->privacy_invoked = 0;
- ieee->ieee802_1x = 1;
- ieee->raw_tx = 0;
-
- ieee80211_softmac_init(ieee);
-
- for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
- INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
-
- for (i = 0; i < 17; i++) {
- ieee->last_rxseq_num[i] = -1;
- ieee->last_rxfrag_num[i] = -1;
- ieee->last_packet_time[i] = 0;
- }
-//These function were added to load crypte module autoly
- ieee80211_tkip_null();
- ieee80211_wep_null();
- ieee80211_ccmp_null();
- return dev;
-
- failed:
- if (dev)
- free_netdev(dev);
- return NULL;
-}
-
-
-void free_ieee80211(struct net_device *dev)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
-
- int i;
- struct list_head *p, *q;
-
-
- ieee80211_softmac_free(ieee);
- del_timer_sync(&ieee->crypt_deinit_timer);
- ieee80211_crypt_deinit_entries(ieee, 1);
-
- for (i = 0; i < WEP_KEYS; i++) {
- struct ieee80211_crypt_data *crypt = ieee->crypt[i];
- if (crypt) {
- if (crypt->ops)
- crypt->ops->deinit(crypt->priv);
- kfree(crypt);
- ieee->crypt[i] = NULL;
- }
- }
-
- ieee80211_networks_free(ieee);
-
- for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
- list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
- kfree(list_entry(p, struct ieee_ibss_seq, list));
- list_del(p);
- }
- }
-
-
- free_netdev(dev);
-}
+++ /dev/null
-/*
- * Original code based Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3 - hostap.o module, common routines
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- * Copyright (c) 2004, Intel Corporation
- *
- * 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. See README and COPYING for
- * more details.
- ******************************************************************************
-
- 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/config.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <linux/uaccess.h>
-#include <linux/ctype.h>
-
-#include "ieee80211.h"
-#include "dot11d.h"
-static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
- struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats)
-{
- struct ieee80211_hdr_4addr *hdr =
- (struct ieee80211_hdr_4addr *)skb->data;
- u16 fc = le16_to_cpu(hdr->frame_ctl);
-
- skb->dev = ieee->dev;
- skb_reset_mac_header(skb);
- skb_pull(skb, ieee80211_get_hdrlen(fc));
- skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_80211_RAW);
- memset(skb->cb, 0, sizeof(skb->cb));
- netif_rx(skb);
-}
-
-
-/* Called only as a tasklet (software IRQ) */
-static struct ieee80211_frag_entry *
-ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
- unsigned int frag, u8 tid, u8 *src, u8 *dst)
-{
- struct ieee80211_frag_entry *entry;
- int i;
-
- for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
- entry = &ieee->frag_cache[tid][i];
- if (entry->skb != NULL &&
- time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
- IEEE80211_DEBUG_FRAG(
- "expiring fragment cache entry "
- "seq=%u last_frag=%u\n",
- entry->seq, entry->last_frag);
- dev_kfree_skb_any(entry->skb);
- entry->skb = NULL;
- }
-
- if (entry->skb != NULL && entry->seq == seq &&
- (entry->last_frag + 1 == frag || frag == -1) &&
- memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
- memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
- return entry;
- }
-
- return NULL;
-}
-
-/* Called only as a tasklet (software IRQ) */
-static struct sk_buff *
-ieee80211_frag_cache_get(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *hdr)
-{
- struct sk_buff *skb = NULL;
- u16 fc = le16_to_cpu(hdr->frame_ctl);
- u16 sc = le16_to_cpu(hdr->seq_ctl);
- unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
- unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
- struct ieee80211_frag_entry *entry;
- struct ieee80211_hdr_3addrqos *hdr_3addrqos;
- struct ieee80211_hdr_4addrqos *hdr_4addrqos;
- u8 tid;
-
- if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid++;
- } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid++;
- } else {
- tid = 0;
- }
-
- if (frag == 0) {
- /* Reserve enough space to fit maximum frame length */
- skb = dev_alloc_skb(ieee->dev->mtu +
- sizeof(struct ieee80211_hdr_4addr) +
- 8 /* LLC */ +
- 2 /* alignment */ +
- 8 /* WEP */ +
- ETH_ALEN /* WDS */ +
- (IEEE80211_QOS_HAS_SEQ(fc) ? 2 : 0) /* QOS Control */);
- if (skb == NULL)
- return NULL;
-
- entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
- ieee->frag_next_idx[tid]++;
- if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
- ieee->frag_next_idx[tid] = 0;
-
- if (entry->skb != NULL)
- dev_kfree_skb_any(entry->skb);
-
- entry->first_frag_time = jiffies;
- entry->seq = seq;
- entry->last_frag = frag;
- entry->skb = skb;
- memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
- memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
- } else {
- /* received a fragment of a frame for which the head fragment
- * should have already been received */
- entry = ieee80211_frag_cache_find(ieee, seq, frag, tid, hdr->addr2,
- hdr->addr1);
- if (entry != NULL) {
- entry->last_frag = frag;
- skb = entry->skb;
- }
- }
-
- return skb;
-}
-
-
-/* Called only as a tasklet (software IRQ) */
-static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *hdr)
-{
- u16 fc = le16_to_cpu(hdr->frame_ctl);
- u16 sc = le16_to_cpu(hdr->seq_ctl);
- unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
- struct ieee80211_frag_entry *entry;
- struct ieee80211_hdr_3addrqos *hdr_3addrqos;
- struct ieee80211_hdr_4addrqos *hdr_4addrqos;
- u8 tid;
-
- if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid++;
- } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid++;
- } else {
- tid = 0;
- }
-
- entry = ieee80211_frag_cache_find(ieee, seq, -1, tid, hdr->addr2,
- hdr->addr1);
-
- if (entry == NULL) {
- IEEE80211_DEBUG_FRAG(
- "could not invalidate fragment cache "
- "entry (seq=%u)\n", seq);
- return -1;
- }
-
- entry->skb = NULL;
- return 0;
-}
-
-
-
-/* ieee80211_rx_frame_mgtmt
- *
- * Responsible for handling management control frames
- *
- * Called by ieee80211_rx */
-static inline int
-ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats, u16 type,
- u16 stype)
-{
- struct ieee80211_hdr_4addr *hdr;
-
- // cheat the the hdr type
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- /* On the struct stats definition there is written that
- * this is not mandatory.... but seems that the probe
- * response parser uses it
- */
- rx_stats->len = skb->len;
- ieee80211_rx_mgt(ieee, (struct ieee80211_hdr_4addr *)skb->data,
- rx_stats);
-
- if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN))) {
- dev_kfree_skb_any(skb);
- return 0;
- }
-
- ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
-
- dev_kfree_skb_any(skb);
-
- return 0;
-
-}
-
-
-
-/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
-/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
-static unsigned char rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
-/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-static unsigned char bridge_tunnel_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
-/* No encapsulation header if EtherType < 0x600 (=length) */
-
-/* Called by ieee80211_rx_frame_decrypt */
-static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
- struct sk_buff *skb, size_t hdrlen)
-{
- struct net_device *dev = ieee->dev;
- u16 fc, ethertype;
- struct ieee80211_hdr_4addr *hdr;
- u8 *pos;
-
- if (skb->len < 24)
- return 0;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
-
- /* check that the frame is unicast frame to us */
- if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_TODS &&
- memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
- memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
- /* ToDS frame with own addr BSSID and DA */
- } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_FROMDS &&
- memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
- /* FromDS frame with own addr as DA */
- } else
- return 0;
-
- if (skb->len < 24 + 8)
- return 0;
-
- /* check for port access entity Ethernet type */
-// pos = skb->data + 24;
- pos = skb->data + hdrlen;
- ethertype = (pos[6] << 8) | pos[7];
- if (ethertype == ETH_P_PAE)
- return 1;
-
- return 0;
-}
-
-/* Called only as a tasklet (software IRQ), by ieee80211_rx */
-static inline int
-ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_crypt_data *crypt)
-{
- struct ieee80211_hdr_4addr *hdr;
- int res, hdrlen;
-
- if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
- return 0;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
-
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- if (ieee->tkip_countermeasures &&
- strcmp(crypt->ops->name, "TKIP") == 0) {
- if (net_ratelimit()) {
- netdev_dbg(ieee->dev,
- "TKIP countermeasures: dropped received packet from %pM\n",
- ieee->dev->name, hdr->addr2);
- }
- return -1;
- }
-#endif
-
- atomic_inc(&crypt->refcnt);
- res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- IEEE80211_DEBUG_DROP(
- "decryption failed (SA=%pM"
- ") res=%d\n", hdr->addr2, res);
- if (res == -2)
- IEEE80211_DEBUG_DROP("Decryption failed ICV "
- "mismatch (key %d)\n",
- skb->data[hdrlen + 3] >> 6);
- ieee->ieee_stats.rx_discards_undecryptable++;
- return -1;
- }
-
- return res;
-}
-
-
-/* Called only as a tasklet (software IRQ), by ieee80211_rx */
-static inline int
-ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
- struct sk_buff *skb, int keyidx,
- struct ieee80211_crypt_data *crypt)
-{
- struct ieee80211_hdr_4addr *hdr;
- int res, hdrlen;
-
- if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
- return 0;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
-
- atomic_inc(&crypt->refcnt);
- res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- netdev_dbg(ieee->dev,
- "MSDU decryption/MIC verification failed (SA=%pM keyidx=%d)\n",
- hdr->addr2, keyidx);
- return -1;
- }
-
- return 0;
-}
-
-
-/* this function is stolen from ipw2200 driver*/
-#define IEEE_PACKET_RETRY_TIME (5*HZ)
-static int is_duplicate_packet(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *header)
-{
- u16 fc = le16_to_cpu(header->frame_ctl);
- u16 sc = le16_to_cpu(header->seq_ctl);
- u16 seq = WLAN_GET_SEQ_SEQ(sc);
- u16 frag = WLAN_GET_SEQ_FRAG(sc);
- u16 *last_seq, *last_frag;
- unsigned long *last_time;
- struct ieee80211_hdr_3addrqos *hdr_3addrqos;
- struct ieee80211_hdr_4addrqos *hdr_4addrqos;
- u8 tid;
-
- //TO2DS and QoS
- if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid++;
- } else if (IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
- hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)header;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid++;
- } else { // no QoS
- tid = 0;
- }
- switch (ieee->iw_mode) {
- case IW_MODE_ADHOC:
- {
- struct list_head *p;
- struct ieee_ibss_seq *entry = NULL;
- u8 *mac = header->addr2;
- int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
-
- list_for_each(p, &ieee->ibss_mac_hash[index]) {
- entry = list_entry(p, struct ieee_ibss_seq, list);
- if (!memcmp(entry->mac, mac, ETH_ALEN))
- break;
- }
- // if (memcmp(entry->mac, mac, ETH_ALEN)){
- if (p == &ieee->ibss_mac_hash[index]) {
- entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
- if (!entry)
- return 0;
-
- memcpy(entry->mac, mac, ETH_ALEN);
- entry->seq_num[tid] = seq;
- entry->frag_num[tid] = frag;
- entry->packet_time[tid] = jiffies;
- list_add(&entry->list, &ieee->ibss_mac_hash[index]);
- return 0;
- }
- last_seq = &entry->seq_num[tid];
- last_frag = &entry->frag_num[tid];
- last_time = &entry->packet_time[tid];
- break;
- }
-
- case IW_MODE_INFRA:
- last_seq = &ieee->last_rxseq_num[tid];
- last_frag = &ieee->last_rxfrag_num[tid];
- last_time = &ieee->last_packet_time[tid];
-
- break;
- default:
- return 0;
- }
-
-// if(tid != 0) {
-// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
-// }
- if ((*last_seq == seq) &&
- time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
- if (*last_frag == frag) {
- //printk(KERN_WARNING "[1] go drop!\n");
- goto drop;
-
- }
- if (*last_frag + 1 != frag)
- /* out-of-order fragment */
- //printk(KERN_WARNING "[2] go drop!\n");
- goto drop;
- } else
- *last_seq = seq;
-
- *last_frag = frag;
- *last_time = jiffies;
- return 0;
-
-drop:
-// BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
-// printk("DUP\n");
-
- return 1;
-}
-
-
-/* All received frames are sent to this function. @skb contains the frame in
- * IEEE 802.11 format, i.e., in the format it was sent over air.
- * This function is called only as a tasklet (software IRQ). */
-int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats)
-{
- struct net_device *dev = ieee->dev;
- //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct ieee80211_hdr_4addr *hdr;
-
- size_t hdrlen;
- u16 fc, type, stype, sc;
- struct net_device_stats *stats;
- unsigned int frag;
- u8 *payload;
- u16 ethertype;
- u8 dst[ETH_ALEN];
- u8 src[ETH_ALEN];
- u8 bssid[ETH_ALEN];
- struct ieee80211_crypt_data *crypt = NULL;
- int keyidx = 0;
-
- // cheat the the hdr type
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- stats = &ieee->stats;
-
- if (skb->len < 10) {
- netdev_info(ieee->dev, "SKB length < 10\n");
- goto rx_dropped;
- }
-
- fc = le16_to_cpu(hdr->frame_ctl);
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
- sc = le16_to_cpu(hdr->seq_ctl);
-
- frag = WLAN_GET_SEQ_FRAG(sc);
-
-//YJ,add,080828,for keep alive
- if ((fc & IEEE80211_FCTL_TODS) != IEEE80211_FCTL_TODS) {
- if (!memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN))
- ieee->NumRxUnicast++;
- } else {
- if (!memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN))
- ieee->NumRxUnicast++;
- }
-//YJ,add,080828,for keep alive,end
-
- hdrlen = ieee80211_get_hdrlen(fc);
-
-
- if (ieee->iw_mode == IW_MODE_MONITOR) {
- ieee80211_monitor_rx(ieee, skb, rx_stats);
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
- return 1;
- }
-
- if (ieee->host_decrypt) {
- int idx = 0;
- if (skb->len >= hdrlen + 3)
- idx = skb->data[hdrlen + 3] >> 6;
- crypt = ieee->crypt[idx];
-
- /* allow NULL decrypt to indicate an station specific override
- * for default encryption */
- if (crypt && (crypt->ops == NULL ||
- crypt->ops->decrypt_mpdu == NULL))
- crypt = NULL;
-
- if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
- /* This seems to be triggered by some (multicast?)
- * frames from other than current BSS, so just drop the
- * frames silently instead of filling system log with
- * these reports. */
- IEEE80211_DEBUG_DROP("Decryption failed (not set)"
- " (SA=%pM)\n",
- hdr->addr2);
- ieee->ieee_stats.rx_discards_undecryptable++;
- goto rx_dropped;
- }
- }
-
- if (skb->len < IEEE80211_DATA_HDR3_LEN)
- goto rx_dropped;
-
- // if QoS enabled, should check the sequence for each of the AC
- if (is_duplicate_packet(ieee, hdr))
- goto rx_dropped;
-
-
- if (type == IEEE80211_FTYPE_MGMT) {
- if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
- goto rx_dropped;
- else
- goto rx_exit;
- }
-
- /* Data frame - extract src/dst addresses */
- switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- case IEEE80211_FCTL_FROMDS:
- memcpy(dst, hdr->addr1, ETH_ALEN);
- memcpy(src, hdr->addr3, ETH_ALEN);
- memcpy(bssid, hdr->addr2, ETH_ALEN);
- break;
- case IEEE80211_FCTL_TODS:
- memcpy(dst, hdr->addr3, ETH_ALEN);
- memcpy(src, hdr->addr2, ETH_ALEN);
- memcpy(bssid, hdr->addr1, ETH_ALEN);
- break;
- case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- if (skb->len < IEEE80211_DATA_HDR4_LEN)
- goto rx_dropped;
- memcpy(dst, hdr->addr3, ETH_ALEN);
- memcpy(src, hdr->addr4, ETH_ALEN);
- memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
- break;
- case 0:
- memcpy(dst, hdr->addr1, ETH_ALEN);
- memcpy(src, hdr->addr2, ETH_ALEN);
- memcpy(bssid, hdr->addr3, ETH_ALEN);
- break;
- }
-
-
- dev->last_rx = jiffies;
-
-
- /* Nullfunc frames may have PS-bit set, so they must be passed to
- * hostap_handle_sta_rx() before being dropped here. */
- if (stype != IEEE80211_STYPE_DATA &&
- stype != IEEE80211_STYPE_DATA_CFACK &&
- stype != IEEE80211_STYPE_DATA_CFPOLL &&
- stype != IEEE80211_STYPE_DATA_CFACKPOLL &&
- stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
- ) {
- if (stype != IEEE80211_STYPE_NULLFUNC)
- IEEE80211_DEBUG_DROP(
- "RX: dropped data frame "
- "with no data (type=0x%02x, "
- "subtype=0x%02x, len=%d)\n",
- type, stype, skb->len);
- goto rx_dropped;
- }
- if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
- goto rx_dropped;
-
- ieee->NumRxDataInPeriod++;
- ieee->NumRxOkTotal++;
- /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
-
- if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
- (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
- goto rx_dropped;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- /* skb: hdr + (possibly fragmented) plaintext payload */
- // PR: FIXME: hostap has additional conditions in the "if" below:
- // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
- if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
- int flen;
- struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
- IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
-
- if (!frag_skb) {
- IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
- "Rx cannot get skb from fragment "
- "cache (morefrag=%d seq=%u frag=%u)\n",
- (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
- WLAN_GET_SEQ_SEQ(sc), frag);
- goto rx_dropped;
- }
- flen = skb->len;
- if (frag != 0)
- flen -= hdrlen;
-
- if (frag_skb->tail + flen > frag_skb->end) {
- netdev_warn(ieee->dev,
- "host decrypted and reassembled frame did not fit skb\n");
- ieee80211_frag_cache_invalidate(ieee, hdr);
- goto rx_dropped;
- }
-
- if (frag == 0) {
- /* copy first fragment (including full headers) into
- * beginning of the fragment cache skb */
- memcpy(skb_put(frag_skb, flen), skb->data, flen);
- } else {
- /* append frame payload to the end of the fragment
- * cache skb */
- memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
- flen);
- }
- dev_kfree_skb_any(skb);
- skb = NULL;
-
- if (fc & IEEE80211_FCTL_MOREFRAGS) {
- /* more fragments expected - leave the skb in fragment
- * cache for now; it will be delivered to upper layers
- * after all fragments have been received */
- goto rx_exit;
- }
-
- /* this was the last fragment and the frame will be
- * delivered, so remove skb from fragment cache */
- skb = frag_skb;
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- ieee80211_frag_cache_invalidate(ieee, hdr);
- }
-
- /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
- * encrypted/authenticated */
- if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
- ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
- goto rx_dropped;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
- if (/*ieee->ieee802_1x &&*/
- ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
-
-#ifdef CONFIG_IEEE80211_DEBUG
- /* pass unencrypted EAPOL frames even if encryption is
- * configured */
- struct eapol *eap = (struct eapol *)(skb->data +
- 24);
- IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
- eap_get_type(eap->type));
-#endif
- } else {
- IEEE80211_DEBUG_DROP(
- "encryption configured, but RX "
- "frame not encrypted (SA=%pM)\n",
- hdr->addr2);
- goto rx_dropped;
- }
- }
-
-#ifdef CONFIG_IEEE80211_DEBUG
- if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
- ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
- struct eapol *eap = (struct eapol *)(skb->data +
- 24);
- IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
- eap_get_type(eap->type));
- }
-#endif
-
- if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
- !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
- IEEE80211_DEBUG_DROP(
- "dropped unencrypted RX data "
- "frame from %pM"
- " (drop_unencrypted=1)\n",
- hdr->addr2);
- goto rx_dropped;
- }
-/*
- if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
- printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
- }
-*/
- /* skb: hdr + (possible reassembled) full plaintext payload */
- payload = skb->data + hdrlen;
- ethertype = (payload[6] << 8) | payload[7];
-
-
- /* convert hdr + possible LLC headers into Ethernet header */
- if (skb->len - hdrlen >= 8 &&
- ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
- ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
- memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
- /* remove RFC1042 or Bridge-Tunnel encapsulation and
- * replace EtherType */
- skb_pull(skb, hdrlen + SNAP_SIZE);
- memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
- memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
- } else {
- u16 len;
- /* Leave Ethernet header part of hdr and full payload */
- skb_pull(skb, hdrlen);
- len = htons(skb->len);
- memcpy(skb_push(skb, 2), &len, 2);
- memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
- memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
- }
-
-
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
-
- if (skb) {
- skb->protocol = eth_type_trans(skb, dev);
- memset(skb->cb, 0, sizeof(skb->cb));
- skb->dev = dev;
- skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
- ieee->last_rx_ps_time = jiffies;
- netif_rx(skb);
- }
-
- rx_exit:
- return 1;
-
- rx_dropped:
- stats->rx_dropped++;
-
- /* Returning 0 indicates to caller that we have not handled the SKB--
- * so it is still allocated and can be used again by underlying
- * hardware as a DMA target */
- return 0;
-}
-
-#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
-
-static inline int ieee80211_is_ofdm_rate(u8 rate)
-{
- switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
- case IEEE80211_OFDM_RATE_6MB:
- case IEEE80211_OFDM_RATE_9MB:
- case IEEE80211_OFDM_RATE_12MB:
- case IEEE80211_OFDM_RATE_18MB:
- case IEEE80211_OFDM_RATE_24MB:
- case IEEE80211_OFDM_RATE_36MB:
- case IEEE80211_OFDM_RATE_48MB:
- case IEEE80211_OFDM_RATE_54MB:
- return 1;
- }
- return 0;
-}
-
-static inline int ieee80211_SignalStrengthTranslate(int CurrSS)
-{
- int RetSS;
-
- // Step 1. Scale mapping.
- if (CurrSS >= 71 && CurrSS <= 100)
- RetSS = 90 + ((CurrSS - 70) / 3);
- else if (CurrSS >= 41 && CurrSS <= 70)
- RetSS = 78 + ((CurrSS - 40) / 3);
- else if (CurrSS >= 31 && CurrSS <= 40)
- RetSS = 66 + (CurrSS - 30);
- else if (CurrSS >= 21 && CurrSS <= 30)
- RetSS = 54 + (CurrSS - 20);
- else if (CurrSS >= 5 && CurrSS <= 20)
- RetSS = 42 + (((CurrSS - 5) * 2) / 3);
- else if (CurrSS == 4)
- RetSS = 36;
- else if (CurrSS == 3)
- RetSS = 27;
- else if (CurrSS == 2)
- RetSS = 18;
- else if (CurrSS == 1)
- RetSS = 9;
- else
- RetSS = CurrSS;
-
- //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
-
- // Step 2. Smoothing.
-
- //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
-
- return RetSS;
-}
-
-static inline void
-ieee80211_extract_country_ie(struct ieee80211_device *ieee,
- struct ieee80211_info_element *info_element,
- struct ieee80211_network *network, u8 *addr2)
-{
- if (IS_DOT11D_ENABLE(ieee)) {
- if (info_element->len != 0) {
- memcpy(network->CountryIeBuf, info_element->data, info_element->len);
- network->CountryIeLen = info_element->len;
-
- if (!IS_COUNTRY_IE_VALID(ieee))
- Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
- }
-
- //
- // 070305, rcnjko: I update country IE watch dog here because
- // some AP (e.g. Cisco 1242) don't include country IE in their
- // probe response frame.
- //
- if (IS_EQUAL_CIE_SRC(ieee, addr2))
- UPDATE_CIE_WATCHDOG(ieee);
- }
-
-}
-
-/* SignalStrengthIndex is 0-100 */
-static int ieee80211_TranslateToDbm(unsigned char SignalStrengthIndex)
-{
- unsigned char SignalPower; // in dBm.
-
- // Translate to dBm (x=0.5y-95).
- SignalPower = (int)SignalStrengthIndex * 7 / 10;
- SignalPower -= 95;
-
- return SignalPower;
-}
-inline int ieee80211_network_init(
- struct ieee80211_device *ieee,
- struct ieee80211_probe_response *beacon,
- struct ieee80211_network *network,
- struct ieee80211_rx_stats *stats)
-{
-#ifdef CONFIG_IEEE80211_DEBUG
- char rates_str[64];
- char *p;
-#endif
- struct ieee80211_info_element *info_element;
- u16 left;
- u8 i;
- short offset;
- u8 curRate = 0, hOpRate = 0, curRate_ex = 0;
-
- /* Pull out fixed field data */
- memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
- network->capability = beacon->capability;
- network->last_scanned = jiffies;
- network->time_stamp[0] = beacon->time_stamp[0];
- network->time_stamp[1] = beacon->time_stamp[1];
- network->beacon_interval = beacon->beacon_interval;
- /* Where to pull this? beacon->listen_interval;*/
- network->listen_interval = 0x0A;
- network->rates_len = network->rates_ex_len = 0;
- network->last_associate = 0;
- network->ssid_len = 0;
- network->flags = 0;
- network->atim_window = 0;
- network->QoS_Enable = 0;
-//by amy 080312
- network->HighestOperaRate = 0;
-//by amy 080312
- network->Turbo_Enable = 0;
- network->CountryIeLen = 0;
- memset(network->CountryIeBuf, 0, MAX_IE_LEN);
-
- if (stats->freq == IEEE80211_52GHZ_BAND) {
- /* for A band (No DS info) */
- network->channel = stats->received_channel;
- } else
- network->flags |= NETWORK_HAS_CCK;
-
- network->wpa_ie_len = 0;
- network->rsn_ie_len = 0;
-
- info_element = &beacon->info_element;
- left = stats->len - ((void *)info_element - (void *)beacon);
- while (left >= sizeof(struct ieee80211_info_element_hdr)) {
- if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
- IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
- info_element->len + sizeof(struct ieee80211_info_element),
- left);
- return 1;
- }
-
- switch (info_element->id) {
- case MFIE_TYPE_SSID:
- if (ieee80211_is_empty_essid(info_element->data,
- info_element->len)) {
- network->flags |= NETWORK_EMPTY_ESSID;
- break;
- }
-
- network->ssid_len = min(info_element->len,
- (u8)IW_ESSID_MAX_SIZE);
- memcpy(network->ssid, info_element->data, network->ssid_len);
- if (network->ssid_len < IW_ESSID_MAX_SIZE)
- memset(network->ssid + network->ssid_len, 0,
- IW_ESSID_MAX_SIZE - network->ssid_len);
-
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
- network->ssid, network->ssid_len);
- break;
-
- case MFIE_TYPE_RATES:
-#ifdef CONFIG_IEEE80211_DEBUG
- p = rates_str;
-#endif
- network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
- for (i = 0; i < network->rates_len; i++) {
- network->rates[i] = info_element->data[i];
- curRate = network->rates[i] & 0x7f;
- if (hOpRate < curRate)
- hOpRate = curRate;
-#ifdef CONFIG_IEEE80211_DEBUG
- p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
-#endif
- if (ieee80211_is_ofdm_rate(info_element->data[i])) {
- network->flags |= NETWORK_HAS_OFDM;
- if (info_element->data[i] &
- IEEE80211_BASIC_RATE_MASK)
- network->flags &=
- ~NETWORK_HAS_CCK;
- }
- }
-
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
- rates_str, network->rates_len);
- break;
-
- case MFIE_TYPE_RATES_EX:
-#ifdef CONFIG_IEEE80211_DEBUG
- p = rates_str;
-#endif
- network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
- for (i = 0; i < network->rates_ex_len; i++) {
- network->rates_ex[i] = info_element->data[i];
- curRate_ex = network->rates_ex[i] & 0x7f;
- if (hOpRate < curRate_ex)
- hOpRate = curRate_ex;
-#ifdef CONFIG_IEEE80211_DEBUG
- p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
-#endif
- if (ieee80211_is_ofdm_rate(info_element->data[i])) {
- network->flags |= NETWORK_HAS_OFDM;
- if (info_element->data[i] &
- IEEE80211_BASIC_RATE_MASK)
- network->flags &=
- ~NETWORK_HAS_CCK;
- }
- }
-
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
- rates_str, network->rates_ex_len);
- break;
-
- case MFIE_TYPE_DS_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
- info_element->data[0]);
- if (stats->freq == IEEE80211_24GHZ_BAND)
- network->channel = info_element->data[0];
- break;
-
- case MFIE_TYPE_FH_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
- break;
-
- case MFIE_TYPE_CF_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
- break;
-
- case MFIE_TYPE_TIM:
-
- if (info_element->len < 4)
- break;
-
- network->dtim_period = info_element->data[1];
-
- if (ieee->state != IEEE80211_LINKED)
- break;
-
- network->last_dtim_sta_time[0] = jiffies;
- network->last_dtim_sta_time[1] = stats->mac_time[1];
-
- network->dtim_data = IEEE80211_DTIM_VALID;
-
- if (info_element->data[0] != 0)
- break;
-
- if (info_element->data[2] & 1)
- network->dtim_data |= IEEE80211_DTIM_MBCAST;
-
- offset = (info_element->data[2] >> 1)*2;
-
- //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
-
- /* add and modified for ps 2008.1.22 */
- if (ieee->assoc_id < 8*offset ||
- ieee->assoc_id > 8*(offset + info_element->len - 3)) {
- break;
- }
-
- offset = (ieee->assoc_id/8) - offset;// + ((aid % 8)? 0 : 1) ;
-
- // printk("offset:%x data:%x, ucast:%d\n", offset,
- // info_element->data[3+offset] ,
- // info_element->data[3+offset] & (1<<(ieee->assoc_id%8)));
-
- if (info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
- network->dtim_data |= IEEE80211_DTIM_UCAST;
-
- break;
-
- case MFIE_TYPE_IBSS_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
- break;
-
- case MFIE_TYPE_CHALLENGE:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
- break;
-
- case MFIE_TYPE_GENERIC:
- //nic is 87B
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
- info_element->len);
- if (info_element->len >= 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0xf2 &&
- info_element->data[3] == 0x01) {
- network->wpa_ie_len = min(info_element->len + 2,
- MAX_WPA_IE_LEN);
- memcpy(network->wpa_ie, info_element,
- network->wpa_ie_len);
- }
-
- if (info_element->len == 7 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0xe0 &&
- info_element->data[2] == 0x4c &&
- info_element->data[3] == 0x01 &&
- info_element->data[4] == 0x02) {
- network->Turbo_Enable = 1;
- }
- if (1 == stats->nic_type) //nic 87
- break;
-
- if (info_element->len >= 5 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0xf2 &&
- info_element->data[3] == 0x02 &&
- info_element->data[4] == 0x00) {
- //printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]);
- //WMM Information Element
- network->wmm_info = info_element->data[6];
- network->QoS_Enable = 1;
- }
-
- if (info_element->len >= 8 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0xf2 &&
- info_element->data[3] == 0x02 &&
- info_element->data[4] == 0x01) {
- // Not care about version at present.
- //WMM Information Element
- //printk(KERN_WARNING "wmm info¶m updated: %x\n", info_element->data[6]);
- network->wmm_info = info_element->data[6];
- //WMM Parameter Element
- memcpy(network->wmm_param, (u8 *)(info_element->data + 8), (info_element->len - 8));
- network->QoS_Enable = 1;
- }
- break;
-
- case MFIE_TYPE_RSN:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
- info_element->len);
- network->rsn_ie_len = min(info_element->len + 2,
- MAX_WPA_IE_LEN);
- memcpy(network->rsn_ie, info_element,
- network->rsn_ie_len);
- break;
- case MFIE_TYPE_COUNTRY:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
- info_element->len);
-// printk("=====>Receive <%s> Country IE\n",network->ssid);
- ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2);
- break;
- default:
- IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
- info_element->id);
- break;
- }
-
- left -= sizeof(struct ieee80211_info_element_hdr) +
- info_element->len;
- info_element = (struct ieee80211_info_element *)
- &info_element->data[info_element->len];
- }
-//by amy 080312
- network->HighestOperaRate = hOpRate;
-//by amy 080312
- network->mode = 0;
- if (stats->freq == IEEE80211_52GHZ_BAND)
- network->mode = IEEE_A;
- else {
- if (network->flags & NETWORK_HAS_OFDM)
- network->mode |= IEEE_G;
- if (network->flags & NETWORK_HAS_CCK)
- network->mode |= IEEE_B;
- }
-
- if (network->mode == 0) {
- IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
- "network.\n",
- escape_essid(network->ssid,
- network->ssid_len),
- network->bssid);
- return 1;
- }
-
- if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
- network->flags |= NETWORK_EMPTY_ESSID;
-
- stats->signal = ieee80211_TranslateToDbm(stats->signalstrength);
- //stats->noise = stats->signal - stats->noise;
- stats->noise = ieee80211_TranslateToDbm(100 - stats->signalstrength) - 25;
- memcpy(&network->stats, stats, sizeof(network->stats));
-
- return 0;
-}
-
-static inline int is_same_network(struct ieee80211_network *src,
- struct ieee80211_network *dst,
- struct ieee80211_device *ieee)
-{
- /* A network is only a duplicate if the channel, BSSID, ESSID
- * and the capability field (in particular IBSS and BSS) all match.
- * We treat all <hidden> with the same BSSID and channel
- * as one network */
- return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
- //((src->ssid_len == dst->ssid_len) &&
- (src->channel == dst->channel) &&
- !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
- (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
- //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
- ((src->capability & WLAN_CAPABILITY_IBSS) ==
- (dst->capability & WLAN_CAPABILITY_IBSS)) &&
- ((src->capability & WLAN_CAPABILITY_BSS) ==
- (dst->capability & WLAN_CAPABILITY_BSS)));
-}
-
-inline void update_network(struct ieee80211_network *dst,
- struct ieee80211_network *src)
-{
- unsigned char quality = src->stats.signalstrength;
- unsigned char signal = 0;
- unsigned char noise = 0;
- if (dst->stats.signalstrength > 0)
- quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
- signal = ieee80211_TranslateToDbm(quality);
- //noise = signal - src->stats.noise;
- if (dst->stats.noise > 0)
- noise = (dst->stats.noise * 5 + src->stats.noise)/6;
- //if(strcmp(dst->ssid, "linksys_lzm000") == 0)
-// printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal);
- memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
- dst->stats.signalstrength = quality;
- dst->stats.signal = signal;
-// printk("==================>stats.signal is %d\n",dst->stats.signal);
- dst->stats.noise = noise;
-
-
- dst->capability = src->capability;
- memcpy(dst->rates, src->rates, src->rates_len);
- dst->rates_len = src->rates_len;
- memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
- dst->rates_ex_len = src->rates_ex_len;
- dst->HighestOperaRate = src->HighestOperaRate;
- //printk("==========>in %s: src->ssid is %s,chan is %d\n",__func__,src->ssid,src->channel);
-
- //YJ,add,080819,for hidden ap
- if (src->ssid_len > 0) {
- //if(src->ssid_len == 13)
- // printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid);
- memset(dst->ssid, 0, dst->ssid_len);
- dst->ssid_len = src->ssid_len;
- memcpy(dst->ssid, src->ssid, src->ssid_len);
- }
- //YJ,add,080819,for hidden ap,end
-
- dst->channel = src->channel;
- dst->mode = src->mode;
- dst->flags = src->flags;
- dst->time_stamp[0] = src->time_stamp[0];
- dst->time_stamp[1] = src->time_stamp[1];
-
- dst->beacon_interval = src->beacon_interval;
- dst->listen_interval = src->listen_interval;
- dst->atim_window = src->atim_window;
- dst->dtim_period = src->dtim_period;
- dst->dtim_data = src->dtim_data;
- dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
- dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
-// printk("update:%s, dtim_period:%x, dtim_data:%x\n", src->ssid, src->dtim_period, src->dtim_data);
- memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
- dst->wpa_ie_len = src->wpa_ie_len;
- memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
- dst->rsn_ie_len = src->rsn_ie_len;
-
- dst->last_scanned = jiffies;
- /* dst->last_associate is not overwritten */
-// disable QoS process now, added by David 2006/7/25
-#if 1
- dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
-/*
- if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter
- memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN);
- }
-*/
- if (src->wmm_param[0].ac_aci_acm_aifsn || \
- src->wmm_param[1].ac_aci_acm_aifsn || \
- src->wmm_param[2].ac_aci_acm_aifsn || \
- src->wmm_param[3].ac_aci_acm_aifsn) {
- memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
- }
- dst->QoS_Enable = src->QoS_Enable;
-#else
- dst->QoS_Enable = 1;//for Rtl8187 simulation
-#endif
- dst->SignalStrength = src->SignalStrength;
- dst->Turbo_Enable = src->Turbo_Enable;
- dst->CountryIeLen = src->CountryIeLen;
- memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
-}
-
-
-inline void
-ieee80211_process_probe_response(struct ieee80211_device *ieee,
- struct ieee80211_probe_response *beacon,
- struct ieee80211_rx_stats *stats)
-{
- struct ieee80211_network network;
- struct ieee80211_network *target;
- struct ieee80211_network *oldest = NULL;
-#ifdef CONFIG_IEEE80211_DEBUG
- struct ieee80211_info_element *info_element = &beacon->info_element;
-#endif
- unsigned long flags;
- short renew;
- u8 wmm_info;
- u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON) ? 1 : 0; //YJ,add,080819,for hidden ap
-
- memset(&network, 0, sizeof(struct ieee80211_network));
-
- IEEE80211_DEBUG_SCAN(
- "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
- escape_essid(info_element->data, info_element->len),
- beacon->header.addr3,
- (beacon->capability & (1<<0xf)) ? '1' : '0',
- (beacon->capability & (1<<0xe)) ? '1' : '0',
- (beacon->capability & (1<<0xd)) ? '1' : '0',
- (beacon->capability & (1<<0xc)) ? '1' : '0',
- (beacon->capability & (1<<0xb)) ? '1' : '0',
- (beacon->capability & (1<<0xa)) ? '1' : '0',
- (beacon->capability & (1<<0x9)) ? '1' : '0',
- (beacon->capability & (1<<0x8)) ? '1' : '0',
- (beacon->capability & (1<<0x7)) ? '1' : '0',
- (beacon->capability & (1<<0x6)) ? '1' : '0',
- (beacon->capability & (1<<0x5)) ? '1' : '0',
- (beacon->capability & (1<<0x4)) ? '1' : '0',
- (beacon->capability & (1<<0x3)) ? '1' : '0',
- (beacon->capability & (1<<0x2)) ? '1' : '0',
- (beacon->capability & (1<<0x1)) ? '1' : '0',
- (beacon->capability & (1<<0x0)) ? '1' : '0');
-
- if (ieee80211_network_init(ieee, beacon, &network, stats)) {
- IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
- escape_essid(info_element->data,
- info_element->len),
- beacon->header.addr3,
- WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
- return;
- }
-
- // For Asus EeePc request,
- // (1) if wireless adapter receive get any 802.11d country code in AP beacon,
- // wireless adapter should follow the country code.
- // (2) If there is no any country code in beacon,
- // then wireless adapter should do active scan from ch1~11 and
- // passive scan from ch12~14
- if (ieee->bGlobalDomain) {
- if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP) {
- // Case 1: Country code
- if (IS_COUNTRY_IE_VALID(ieee)) {
- if (!IsLegalChannel(ieee, network.channel)) {
- printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
- return;
- }
- }
- // Case 2: No any country code.
- else {
- // Filter over channel ch12~14
- if (network.channel > 11) {
- printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
- return;
- }
- }
- } else {
- // Case 1: Country code
- if (IS_COUNTRY_IE_VALID(ieee)) {
- if (!IsLegalChannel(ieee, network.channel)) {
- printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n", network.channel);
- return;
- }
- }
- // Case 2: No any country code.
- else {
- // Filter over channel ch12~14
- if (network.channel > 14) {
- printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n", network.channel);
- return;
- }
- }
- }
- }
- /* The network parsed correctly -- so now we scan our known networks
- * to see if we can find it in our list.
- *
- * NOTE: This search is definitely not optimized. Once its doing
- * the "right thing" we'll optimize it for efficiency if
- * necessary */
-
- /* Search for this entry in the list and update it if it is
- * already there. */
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (is_same_network(&ieee->current_network, &network, ieee)) {
- wmm_info = ieee->current_network.wmm_info;
- //YJ,add,080819,for hidden ap
- if (is_beacon == 0)
- network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
- else if (ieee->state == IEEE80211_LINKED)
- ieee->NumRxBcnInPeriod++;
- //YJ,add,080819,for hidden ap,end
- //printk("====>network.ssid=%s cur_ssid=%s\n", network.ssid, ieee->current_network.ssid);
- update_network(&ieee->current_network, &network);
- }
-
- list_for_each_entry(target, &ieee->network_list, list) {
- if (is_same_network(target, &network, ieee))
- break;
- if ((oldest == NULL) ||
- (target->last_scanned < oldest->last_scanned))
- oldest = target;
- }
-
- /* If we didn't find a match, then get a new network slot to initialize
- * with this beacon's information */
- if (&target->list == &ieee->network_list) {
- if (list_empty(&ieee->network_free_list)) {
- /* If there are no more slots, expire the oldest */
- list_del(&oldest->list);
- target = oldest;
- IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
- "network list.\n",
- escape_essid(target->ssid,
- target->ssid_len),
- target->bssid);
- } else {
- /* Otherwise just pull from the free list */
- target = list_entry(ieee->network_free_list.next,
- struct ieee80211_network, list);
- list_del(ieee->network_free_list.next);
- }
-
-
-#ifdef CONFIG_IEEE80211_DEBUG
- IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
- escape_essid(network.ssid,
- network.ssid_len),
- network.bssid,
- WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
-#endif
-
- memcpy(target, &network, sizeof(*target));
- list_add_tail(&target->list, &ieee->network_list);
- } else {
- IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
- escape_essid(target->ssid,
- target->ssid_len),
- target->bssid,
- WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
-
- /* 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
- */
- renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
- //YJ,add,080819,for hidden ap
- if (is_beacon == 0)
- network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
- //if(strncmp(network.ssid, "linksys-c",9) == 0)
- // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
- if (((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
- && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
- || ((ieee->current_network.ssid_len == network.ssid_len) && (strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0) && (ieee->state == IEEE80211_NOLINK))))
- renew = 1;
- //YJ,add,080819,for hidden ap,end
- update_network(target, &network);
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *header,
- struct ieee80211_rx_stats *stats)
-{
- switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
-
- case IEEE80211_STYPE_BEACON:
- IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
- IEEE80211_DEBUG_SCAN("Beacon\n");
- ieee80211_process_probe_response(
- ieee, (struct ieee80211_probe_response *)header, stats);
- break;
-
- case IEEE80211_STYPE_PROBE_RESP:
- IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
- IEEE80211_DEBUG_SCAN("Probe response\n");
- ieee80211_process_probe_response(
- ieee, (struct ieee80211_probe_response *)header, stats);
- break;
- }
-}
+++ /dev/null
-/* IEEE 802.11 SoftMAC layer
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * Mostly extracted from the rtl8180-sa2400 driver for the
- * in-kernel generic ieee802.11 stack.
- *
- * Few lines might be stolen from other part of the ieee80211
- * stack. Copyright who own it's copyright
- *
- * WPA code stolen from the ipw2200 driver.
- * Copyright who own it's copyright.
- *
- * released under the GPL
- */
-
-#include "ieee80211.h"
-
-#include <linux/random.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/uaccess.h>
-#include <linux/etherdevice.h>
-
-#include "dot11d.h"
-
-short ieee80211_is_54g(const struct ieee80211_network *net)
-{
- return (net->rates_ex_len > 0) || (net->rates_len > 4);
-}
-
-short ieee80211_is_shortslot(const struct ieee80211_network *net)
-{
- return net->capability & WLAN_CAPABILITY_SHORT_SLOT;
-}
-
-/* returns the total length needed for placing the RATE MFIE
- * tag and the EXTENDED RATE MFIE tag if needed.
- * It encludes two bytes per tag for the tag itself and its len
- */
-static unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
-{
- unsigned int rate_len = 0;
-
- if (ieee->modulation & IEEE80211_CCK_MODULATION)
- rate_len = IEEE80211_CCK_RATE_LEN + 2;
-
- if (ieee->modulation & IEEE80211_OFDM_MODULATION)
-
- rate_len += IEEE80211_OFDM_RATE_LEN + 2;
-
- return rate_len;
-}
-
-/* place the MFIE rate, tag to the memory (double) poised.
- * Then it updates the pointer so that it points after the new MFIE tag added.
- */
-static void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
-
- if (ieee->modulation & IEEE80211_CCK_MODULATION) {
- *tag++ = MFIE_TYPE_RATES;
- *tag++ = 4;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
- }
-
- /* We may add an option for custom rates that specific HW might support */
- *tag_p = tag;
-}
-
-static void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
-
- if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
- *tag++ = MFIE_TYPE_RATES_EX;
- *tag++ = 8;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
-
- }
- /* We may add an option for custom rates that specific HW might support */
- *tag_p = tag;
-}
-
-static void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
-
- *tag++ = MFIE_TYPE_GENERIC; /* 0 */
- *tag++ = 7;
- *tag++ = 0x00;
- *tag++ = 0x50;
- *tag++ = 0xf2;
- *tag++ = 0x02; /* 5 */
- *tag++ = 0x00;
- *tag++ = 0x01;
-#ifdef SUPPORT_USPD
- if (ieee->current_network.wmm_info & 0x80)
- *tag++ = 0x0f|MAX_SP_Len;
- else
- *tag++ = MAX_SP_Len;
-#else
- *tag++ = MAX_SP_Len;
-#endif
- *tag_p = tag;
-}
-
-static void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
- *tag++ = MFIE_TYPE_GENERIC; /* 0 */
- *tag++ = 7;
- *tag++ = 0x00;
- *tag++ = 0xe0;
- *tag++ = 0x4c;
- *tag++ = 0x01; /* 5 */
- *tag++ = 0x02;
- *tag++ = 0x11;
- *tag++ = 0x00;
- *tag_p = tag;
- printk(KERN_ALERT "This is enable turbo mode IE process\n");
-}
-
-static void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
-{
- int nh;
- nh = (ieee->mgmt_queue_head + 1) % MGMT_QUEUE_NUM;
-
- ieee->mgmt_queue_head = nh;
- ieee->mgmt_queue_ring[nh] = skb;
-}
-
-static struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
-{
- struct sk_buff *ret;
-
- if (ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
- return NULL;
-
- ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
-
- ieee->mgmt_queue_tail =
- (ieee->mgmt_queue_tail + 1) % MGMT_QUEUE_NUM;
-
- return ret;
-}
-
-static void init_mgmt_queue(struct ieee80211_device *ieee)
-{
- ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
-}
-
-void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
-
-inline void softmac_mgmt_xmit(struct sk_buff *skb,
- struct ieee80211_device *ieee)
-{
- unsigned long flags;
- short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
- struct ieee80211_hdr_3addr *header =
- (struct ieee80211_hdr_3addr *) skb->data;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- /* called with 2nd param 0, no mgmt lock required */
- ieee80211_sta_wakeup(ieee, 0);
-
- if (single) {
- if (ieee->queue_stop) {
- enqueue_mgmt(ieee, skb);
- } else {
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- /* avoid watchdog triggers */
- ieee->dev->trans_start = jiffies;
- ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
- } else {
- spin_unlock_irqrestore(&ieee->lock, flags);
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
-
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- /* avoid watchdog triggers */
- ieee->dev->trans_start = jiffies;
- ieee->softmac_hard_start_xmit(skb, ieee->dev);
-
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
- }
-}
-
-inline void softmac_ps_mgmt_xmit(struct sk_buff *skb,
- struct ieee80211_device *ieee)
-{
- short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
- struct ieee80211_hdr_3addr *header =
- (struct ieee80211_hdr_3addr *) skb->data;
-
- if (single) {
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- /* avoid watchdog triggers */
- ieee->dev->trans_start = jiffies;
- ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
- } else {
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- /* avoid watchdog triggers */
- ieee->dev->trans_start = jiffies;
- ieee->softmac_hard_start_xmit(skb, ieee->dev);
- }
-}
-
-inline struct sk_buff *
-ieee80211_disassociate_skb(struct ieee80211_network *beacon,
- struct ieee80211_device *ieee, u8 asRsn)
-{
- struct sk_buff *skb;
- struct ieee80211_disassoc_frame *disass;
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc_frame));
- if (!skb)
- return NULL;
-
- disass = (struct ieee80211_disassoc_frame *) skb_put(skb, sizeof(struct ieee80211_disassoc_frame));
- disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
- disass->header.duration_id = 0;
-
- memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
- memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
-
- disass->reasoncode = asRsn;
- return skb;
-}
-
-void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta, u8 asRsn)
-{
- struct ieee80211_network *beacon = &ieee->current_network;
- struct sk_buff *skb;
- skb = ieee80211_disassociate_skb(beacon, ieee, asRsn);
- if (skb)
- softmac_mgmt_xmit(skb, ieee);
-}
-
-inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
-{
- unsigned int len, rate_len;
- u8 *tag;
- struct sk_buff *skb;
- struct ieee80211_probe_request *req;
-
- len = ieee->current_network.ssid_len;
-
- rate_len = ieee80211_MFIE_rate_len(ieee);
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
- 2 + len + rate_len);
- if (!skb)
- return NULL;
-
- req = (struct ieee80211_probe_request *) skb_put(skb, sizeof(struct ieee80211_probe_request));
- req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- req->header.duration_id = 0; /* FIXME: is this OK ? */
-
- memset(req->header.addr1, 0xff, ETH_ALEN);
- memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memset(req->header.addr3, 0xff, ETH_ALEN);
-
- tag = (u8 *) skb_put(skb, len + 2 + rate_len);
-
- *tag++ = MFIE_TYPE_SSID;
- *tag++ = len;
- memcpy(tag, ieee->current_network.ssid, len);
- tag += len;
- ieee80211_MFIE_Brate(ieee, &tag);
- ieee80211_MFIE_Grate(ieee, &tag);
-
- return skb;
-}
-
-struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
-
-static void ieee80211_send_beacon(struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
-
- skb = ieee80211_get_beacon_(ieee);
-
- if (skb) {
- softmac_mgmt_xmit(skb, ieee);
- ieee->softmac_stats.tx_beacons++;
- dev_kfree_skb_any(skb);
- }
-
- ieee->beacon_timer.expires = jiffies +
- (MSECS(ieee->current_network.beacon_interval - 5));
-
- if (ieee->beacon_txing)
- add_timer(&ieee->beacon_timer);
-}
-
-
-static void ieee80211_send_beacon_cb(unsigned long _ieee)
-{
- struct ieee80211_device *ieee =
- (struct ieee80211_device *) _ieee;
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->beacon_lock, flags);
- ieee80211_send_beacon(ieee);
- spin_unlock_irqrestore(&ieee->beacon_lock, flags);
-}
-
-static void ieee80211_send_probe(struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
-
- skb = ieee80211_probe_req(ieee);
- if (skb) {
- softmac_mgmt_xmit(skb, ieee);
- ieee->softmac_stats.tx_probe_rq++;
- }
-}
-
-static void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
-{
- if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)) {
- ieee80211_send_probe(ieee);
- ieee80211_send_probe(ieee);
- }
-}
-
-/* this performs syncro scan blocking the caller until all channels
- * in the allowed channel map has been checked.
- */
-static void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
-{
- short ch = 0;
- u8 channel_map[MAX_CHANNEL_NUMBER+1];
- memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
- down(&ieee->scan_sem);
-
- while (1) {
- do {
- ch++;
- if (ch > MAX_CHANNEL_NUMBER)
- goto out; /* scan completed */
-
- } while (!channel_map[ch]);
- /* this function can be called in two situations
- * 1- We have switched to ad-hoc mode and we are
- * performing a complete syncro scan before conclude
- * there are no interesting cell and to create a
- * new one. In this case the link state is
- * IEEE80211_NOLINK until we found an interesting cell.
- * If so the ieee8021_new_net, called by the RX path
- * will set the state to IEEE80211_LINKED, so we stop
- * scanning
- * 2- We are linked and the root uses run iwlist scan.
- * So we switch to IEEE80211_LINKED_SCANNING to remember
- * that we are still logically linked (not interested in
- * new network events, despite for updating the net list,
- * but we are temporarily 'unlinked' as the driver shall
- * not filter RX frames and the channel is changing.
- * So the only situation in witch are interested is to check
- * if the state become LINKED because of the #1 situation
- */
-
- if (ieee->state == IEEE80211_LINKED)
- goto out;
-
- ieee->set_chan(ieee->dev, ch);
- if (channel_map[ch] == 1)
- ieee80211_send_probe_requests(ieee);
-
- /* this prevent excessive time wait when we
- * need to wait for a syncro scan to end..
- */
- if (ieee->sync_scan_hurryup)
- goto out;
-
- msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
- }
-out:
- ieee->sync_scan_hurryup = 0;
- up(&ieee->scan_sem);
- if (IS_DOT11D_ENABLE(ieee))
- DOT11D_ScanComplete(ieee);
-}
-
-void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee)
-{
- int ch;
- unsigned int watch_dog = 0;
- u8 channel_map[MAX_CHANNEL_NUMBER+1];
- memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
- down(&ieee->scan_sem);
- ch = ieee->current_network.channel;
-
- while (1) {
- /* this function can be called in two situations
- * 1- We have switched to ad-hoc mode and we are
- * performing a complete syncro scan before conclude
- * there are no interesting cell and to create a
- * new one. In this case the link state is
- * IEEE80211_NOLINK until we found an interesting cell.
- * If so the ieee8021_new_net, called by the RX path
- * will set the state to IEEE80211_LINKED, so we stop
- * scanning
- * 2- We are linked and the root uses run iwlist scan.
- * So we switch to IEEE80211_LINKED_SCANNING to remember
- * that we are still logically linked (not interested in
- * new network events, despite for updating the net list,
- * but we are temporarily 'unlinked' as the driver shall
- * not filter RX frames and the channel is changing.
- * So the only situation in witch are interested is to check
- * if the state become LINKED because of the #1 situation
- */
- if (ieee->state == IEEE80211_LINKED)
- goto out;
-
- if (channel_map[ieee->current_network.channel] > 0)
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
- if (channel_map[ieee->current_network.channel] == 1)
- ieee80211_send_probe_requests(ieee);
-
- msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
-
- do {
- if (watch_dog++ >= MAX_CHANNEL_NUMBER)
- goto out; /* scan completed */
-
- ieee->current_network.channel = (ieee->current_network.channel + 1)%MAX_CHANNEL_NUMBER;
- } while (!channel_map[ieee->current_network.channel]);
- }
-out:
- ieee->actscanning = false;
- up(&ieee->scan_sem);
- if (IS_DOT11D_ENABLE(ieee))
- DOT11D_ScanComplete(ieee);
-}
-
-static void ieee80211_softmac_scan_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
- static short watchdog;
- u8 channel_map[MAX_CHANNEL_NUMBER+1];
- memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
- down(&ieee->scan_sem);
-
- do {
- ieee->current_network.channel =
- (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
- if (watchdog++ > MAX_CHANNEL_NUMBER)
- goto out; /* no good chans */
- } while (!channel_map[ieee->current_network.channel]);
-
- if (ieee->scanning == 0) {
- printk("error out, scanning = 0\n");
- goto out;
- }
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- if (channel_map[ieee->current_network.channel] == 1)
- ieee80211_send_probe_requests(ieee);
-
- queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
- up(&ieee->scan_sem);
- return;
-out:
- ieee->actscanning = false;
- watchdog = 0;
- ieee->scanning = 0;
- up(&ieee->scan_sem);
-
- if (IS_DOT11D_ENABLE(ieee))
- DOT11D_ScanComplete(ieee);
- return;
-}
-
-static void ieee80211_beacons_start(struct ieee80211_device *ieee)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->beacon_lock, flags);
-
- ieee->beacon_txing = 1;
- ieee80211_send_beacon(ieee);
-
- spin_unlock_irqrestore(&ieee->beacon_lock, flags);
-}
-
-static void ieee80211_beacons_stop(struct ieee80211_device *ieee)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->beacon_lock, flags);
-
- ieee->beacon_txing = 0;
- del_timer_sync(&ieee->beacon_timer);
-
- spin_unlock_irqrestore(&ieee->beacon_lock, flags);
-}
-
-void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
-{
- if (ieee->stop_send_beacons)
- ieee->stop_send_beacons(ieee->dev);
- if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
- ieee80211_beacons_stop(ieee);
-}
-
-void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
-{
- if (ieee->start_send_beacons)
- ieee->start_send_beacons(ieee->dev);
- if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
- ieee80211_beacons_start(ieee);
-}
-
-static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
-{
- down(&ieee->scan_sem);
-
- if (ieee->scanning == 1) {
- ieee->scanning = 0;
- cancel_delayed_work(&ieee->softmac_scan_wq);
- }
-
- up(&ieee->scan_sem);
-}
-
-void ieee80211_stop_scan(struct ieee80211_device *ieee)
-{
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
- ieee80211_softmac_stop_scan(ieee);
- else
- ieee->stop_scan(ieee->dev);
-}
-
-/* called with ieee->lock held */
-void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
-{
- if (IS_DOT11D_ENABLE(ieee)) {
- if (IS_COUNTRY_IE_VALID(ieee))
- RESET_CIE_WATCHDOG(ieee);
- }
-
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
- if (ieee->scanning == 0) {
- ieee->scanning = 1;
-#if 1
- queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
-#endif
- }
- }else
- ieee->start_scan(ieee->dev);
-}
-
-/* called with wx_sem held */
-void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
-{
- if (IS_DOT11D_ENABLE(ieee)) {
- if (IS_COUNTRY_IE_VALID(ieee))
- RESET_CIE_WATCHDOG(ieee);
- }
- ieee->sync_scan_hurryup = 0;
-
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
- ieee80211_softmac_scan_syncro(ieee);
- else
- ieee->scan_syncro(ieee->dev);
-}
-
-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;
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen);
-
- if (!skb)
- return NULL;
-
- auth = (struct ieee80211_authentication *)
- skb_put(skb, sizeof(struct ieee80211_authentication));
-
- auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
- if (challengelen)
- auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
-
- auth->header.duration_id = 0x013a; /* FIXME */
-
- memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
- memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
-
- auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
-
- auth->transaction = cpu_to_le16(ieee->associate_seq);
- ieee->associate_seq++;
-
- auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
-
- return skb;
-}
-
-static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee,
- u8 *dest)
-{
- u8 *tag;
- int beacon_size;
- struct ieee80211_probe_response *beacon_buf;
- struct sk_buff *skb;
- int encrypt;
- int atim_len, erp_len;
- struct ieee80211_crypt_data *crypt;
-
- char *ssid = ieee->current_network.ssid;
- int ssid_len = ieee->current_network.ssid_len;
- int rate_len = ieee->current_network.rates_len+2;
- int rate_ex_len = ieee->current_network.rates_ex_len;
- int wpa_ie_len = ieee->wpa_ie_len;
- if (rate_ex_len > 0)
- rate_ex_len += 2;
-
- if (ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
- atim_len = 4;
- else
- atim_len = 0;
-
- if (ieee80211_is_54g(&ieee->current_network))
- erp_len = 3;
- else
- erp_len = 0;
-
- beacon_size = sizeof(struct ieee80211_probe_response)+
- ssid_len
- +3 /* channel */
- +rate_len
- +rate_ex_len
- +atim_len
- +wpa_ie_len
- +erp_len;
-
- skb = dev_alloc_skb(beacon_size);
-
- if (!skb)
- return NULL;
-
- beacon_buf = (struct ieee80211_probe_response *) skb_put(skb, beacon_size);
-
- memcpy(beacon_buf->header.addr1, dest, ETH_ALEN);
- memcpy(beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
-
- beacon_buf->header.duration_id = 0; /* FIXME */
- beacon_buf->beacon_interval =
- cpu_to_le16(ieee->current_network.beacon_interval);
- beacon_buf->capability =
- cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
-
- if (ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
- beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-
- crypt = ieee->crypt[ieee->tx_keyidx];
-
- encrypt = ieee->host_encrypt && crypt && crypt->ops &&
- ((0 == strcmp(crypt->ops->name, "WEP")) || wpa_ie_len);
-
- if (encrypt)
- beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-
-
- beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
-
- beacon_buf->info_element.id = MFIE_TYPE_SSID;
- beacon_buf->info_element.len = ssid_len;
-
- tag = (u8 *) beacon_buf->info_element.data;
-
- memcpy(tag, ssid, ssid_len);
-
- tag += ssid_len;
-
- *(tag++) = MFIE_TYPE_RATES;
- *(tag++) = rate_len - 2;
- memcpy(tag, ieee->current_network.rates, rate_len-2);
- tag += rate_len - 2;
-
- *(tag++) = MFIE_TYPE_DS_SET;
- *(tag++) = 1;
- *(tag++) = ieee->current_network.channel;
-
- if (atim_len) {
- *(tag++) = MFIE_TYPE_IBSS_SET;
- *(tag++) = 2;
- *((u16 *)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
- tag += 2;
- }
-
- if (erp_len) {
- *(tag++) = MFIE_TYPE_ERP;
- *(tag++) = 1;
- *(tag++) = 0;
- }
-
- if (rate_ex_len) {
- *(tag++) = MFIE_TYPE_RATES_EX;
- *(tag++) = rate_ex_len-2;
- memcpy(tag, ieee->current_network.rates_ex, rate_ex_len-2);
- tag += rate_ex_len - 2;
- }
-
- if (wpa_ie_len) {
- if (ieee->iw_mode == IW_MODE_ADHOC) {
- /* as Windows will set pairwise key same as the group
- * key which is not allowed in Linux, so set this for
- * IOT issue.
- */
- memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
- }
-
- memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
- }
- skb->dev = ieee->dev;
- return skb;
-}
-
-static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee,
- u8 *dest)
-{
- struct sk_buff *skb;
- u8 *tag;
-
- struct ieee80211_crypt_data *crypt;
- struct ieee80211_assoc_response_frame *assoc;
- short encrypt;
-
- unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
- int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
-
- skb = dev_alloc_skb(len);
-
- if (!skb)
- return NULL;
-
- assoc = (struct ieee80211_assoc_response_frame *)
- skb_put(skb, sizeof(struct ieee80211_assoc_response_frame));
-
- assoc->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
- memcpy(assoc->header.addr1, dest, ETH_ALEN);
- memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
- WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
-
- if (ieee->short_slot)
- assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-
- if (ieee->host_encrypt)
- crypt = ieee->crypt[ieee->tx_keyidx];
- else
- crypt = NULL;
-
- encrypt = (crypt && crypt->ops);
-
- if (encrypt)
- assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-
- assoc->status = 0;
- assoc->aid = cpu_to_le16(ieee->assoc_id);
- if (ieee->assoc_id == 0x2007)
- ieee->assoc_id = 0;
- else
- ieee->assoc_id++;
-
- tag = (u8 *) skb_put(skb, rate_len);
-
- ieee80211_MFIE_Brate(ieee, &tag);
- ieee80211_MFIE_Grate(ieee, &tag);
-
- return skb;
-}
-
-static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,
- int status, u8 *dest)
-{
- struct sk_buff *skb;
- struct ieee80211_authentication *auth;
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1);
-
- if (!skb)
- return NULL;
-
- skb->len = sizeof(struct ieee80211_authentication);
-
- auth = (struct ieee80211_authentication *)skb->data;
-
- auth->status = cpu_to_le16(status);
- auth->transaction = cpu_to_le16(2);
- auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
-
- memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(auth->header.addr1, dest, ETH_ALEN);
- auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
- return skb;
-}
-
-static struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee, short pwr)
-{
- struct sk_buff *skb;
- struct ieee80211_hdr_3addr *hdr;
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
-
- if (!skb)
- return NULL;
-
- hdr = (struct ieee80211_hdr_3addr *)skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
-
- memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
- memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
-
- hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
- (pwr ? IEEE80211_FCTL_PM:0));
-
- return skb;
-}
-
-static void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest)
-{
- struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
-
- if (buf) {
- softmac_mgmt_xmit(buf, ieee);
- dev_kfree_skb_any(buf);
- }
-}
-
-static void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8 *dest)
-{
- struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
-
- if (buf) {
- softmac_mgmt_xmit(buf, ieee);
- dev_kfree_skb_any(buf);
- }
-}
-
-static void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
-{
- struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
-
- if (buf) {
- softmac_mgmt_xmit(buf, ieee);
- dev_kfree_skb_any(buf);
- }
-}
-
-inline struct sk_buff *
-ieee80211_association_req(struct ieee80211_network *beacon,
- struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
-
- struct ieee80211_assoc_request_frame *hdr;
- u8 *tag;
- unsigned int wpa_len = beacon->wpa_ie_len;
-#if 1
- /* for testing purpose */
- unsigned int rsn_len = beacon->rsn_ie_len;
-#endif
- unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
- unsigned int wmm_info_len = beacon->QoS_Enable?9:0;
- unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
-
- u8 encry_proto = ieee->wpax_type_notify & 0xff;
-
- int len = 0;
-
- /* [0] Notify type of encryption: WPA/WPA2
- * [1] pair wise type
- * [2] authen type
- */
- if (ieee->wpax_type_set) {
- if (IEEE_PROTO_WPA == encry_proto) {
- rsn_len = 0;
- } else if (IEEE_PROTO_RSN == encry_proto) {
- wpa_len = 0;
- }
- }
- len = sizeof(struct ieee80211_assoc_request_frame)+
- + beacon->ssid_len /* essid tagged val */
- + rate_len /* rates tagged val */
- + wpa_len
- + rsn_len
- + wmm_info_len
- + turbo_info_len;
-
- skb = dev_alloc_skb(len);
-
- if (!skb)
- return NULL;
-
- hdr = (struct ieee80211_assoc_request_frame *)
- skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
-
- hdr->header.frame_control = IEEE80211_STYPE_ASSOC_REQ;
- hdr->header.duration_id = 37; /* FIXME */
- memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
- memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
- memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN); /* for HW security */
-
- hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
- if (beacon->capability & WLAN_CAPABILITY_PRIVACY)
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
- if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
-
- if (ieee->short_slot)
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-
- hdr->listen_interval = 0xa; /* FIXME */
-
- hdr->info_element.id = MFIE_TYPE_SSID;
-
- hdr->info_element.len = beacon->ssid_len;
- tag = skb_put(skb, beacon->ssid_len);
- memcpy(tag, beacon->ssid, beacon->ssid_len);
-
- tag = skb_put(skb, rate_len);
-
- ieee80211_MFIE_Brate(ieee, &tag);
- ieee80211_MFIE_Grate(ieee, &tag);
-
- /* add rsn==0 condition for ap's mix security mode(wpa+wpa2)
- * choose AES encryption as default algorithm while using mixed mode.
- */
-
- tag = skb_put(skb, ieee->wpa_ie_len);
- memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
-
- tag = skb_put(skb, wmm_info_len);
- if (wmm_info_len)
- ieee80211_WMM_Info(ieee, &tag);
-
- tag = skb_put(skb, turbo_info_len);
- if (turbo_info_len)
- ieee80211_TURBO_Info(ieee, &tag);
-
- return skb;
-}
-
-void ieee80211_associate_abort(struct ieee80211_device *ieee)
-{
- unsigned long flags;
- spin_lock_irqsave(&ieee->lock, flags);
-
- ieee->associate_seq++;
-
- /* don't scan, and avoid to have the RX path possibly
- * try again to associate. Even do not react to AUTH or
- * ASSOC response. Just wait for the retry wq to be scheduled.
- * Here we will check if there are good nets to associate
- * with, so we retry or just get back to NO_LINK and scanning
- */
- if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING) {
- IEEE80211_DEBUG_MGMT("Authentication failed\n");
- ieee->softmac_stats.no_auth_rs++;
- } else {
- IEEE80211_DEBUG_MGMT("Association failed\n");
- ieee->softmac_stats.no_ass_rs++;
- }
-
- ieee->state = IEEE80211_ASSOCIATING_RETRY;
-
- queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-static void ieee80211_associate_abort_cb(unsigned long dev)
-{
- ieee80211_associate_abort((struct ieee80211_device *) dev);
-}
-
-static void ieee80211_associate_step1(struct ieee80211_device *ieee)
-{
- struct ieee80211_network *beacon = &ieee->current_network;
- struct sk_buff *skb;
-
- IEEE80211_DEBUG_MGMT("Stopping scan\n");
- ieee->softmac_stats.tx_auth_rq++;
- skb = ieee80211_authentication_req(beacon, ieee, 0);
- if (!skb) {
- ieee80211_associate_abort(ieee);
- } else {
- ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING;
- IEEE80211_DEBUG_MGMT("Sending authentication request\n");
- softmac_mgmt_xmit(skb, ieee);
- /* BUGON when you try to add_timer twice, using mod_timer may
- * be better.
- */
- if (!timer_pending(&ieee->associate_timer)) {
- ieee->associate_timer.expires = jiffies + (HZ / 2);
- add_timer(&ieee->associate_timer);
- }
- /* If call dev_kfree_skb_any,a warning will ocur....
- * KERNEL: assertion (!atomic_read(&skb->users)) failed at
- * net/core/dev.c (1708)
- */
- }
-}
-
-static void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge,
- int chlen)
-{
- u8 *c;
- struct sk_buff *skb;
- struct ieee80211_network *beacon = &ieee->current_network;
- del_timer_sync(&ieee->associate_timer);
- ieee->associate_seq++;
- ieee->softmac_stats.tx_auth_rq++;
-
- skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
- if (!skb)
- ieee80211_associate_abort(ieee);
- else {
- c = skb_put(skb, chlen+2);
- *(c++) = MFIE_TYPE_CHALLENGE;
- *(c++) = chlen;
- memcpy(c, challenge, chlen);
-
- IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
-
- ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr));
-
- softmac_mgmt_xmit(skb, ieee);
- if (!timer_pending(&ieee->associate_timer)) {
- ieee->associate_timer.expires = jiffies + (HZ / 2);
- add_timer(&ieee->associate_timer);
- }
- dev_kfree_skb_any(skb);
- }
- kfree(challenge);
-}
-
-static void ieee80211_associate_step2(struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
- struct ieee80211_network *beacon = &ieee->current_network;
-
- del_timer_sync(&ieee->associate_timer);
-
- IEEE80211_DEBUG_MGMT("Sending association request\n");
- ieee->softmac_stats.tx_ass_rq++;
- skb = ieee80211_association_req(beacon, ieee);
- if (!skb)
- ieee80211_associate_abort(ieee);
- else {
- softmac_mgmt_xmit(skb, ieee);
- if (!timer_pending(&ieee->associate_timer)) {
- ieee->associate_timer.expires = jiffies + (HZ / 2);
- add_timer(&ieee->associate_timer);
- }
- }
-}
-
-static void ieee80211_associate_complete_wq(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
-
- printk(KERN_INFO "Associated successfully\n");
- if (ieee80211_is_54g(&ieee->current_network) &&
- (ieee->modulation & IEEE80211_OFDM_MODULATION)) {
- ieee->rate = 540;
- printk(KERN_INFO"Using G rates\n");
- } else {
- ieee->rate = 110;
- printk(KERN_INFO"Using B rates\n");
- }
- ieee->link_change(ieee->dev);
- notify_wx_assoc_event(ieee);
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
- netif_carrier_on(ieee->dev);
-}
-
-static void ieee80211_associate_complete(struct ieee80211_device *ieee)
-{
- del_timer_sync(&ieee->associate_timer);
-
- ieee->state = IEEE80211_LINKED;
- IEEE80211_DEBUG_MGMT("Successfully associated\n");
-
- queue_work(ieee->wq, &ieee->associate_complete_wq);
-}
-
-static void ieee80211_associate_procedure_wq(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
-
- ieee->sync_scan_hurryup = 1;
- down(&ieee->wx_sem);
-
- if (ieee->data_hard_stop)
- ieee->data_hard_stop(ieee->dev);
-
- ieee80211_stop_scan(ieee);
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
- ieee->associate_seq = 1;
- ieee80211_associate_step1(ieee);
-
- up(&ieee->wx_sem);
-}
-
-inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee,
- struct ieee80211_network *net)
-{
- u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
- int tmp_ssid_len = 0;
-
- short apset, ssidset, ssidbroad, apmatch, ssidmatch;
-
- /* we are interested in new new only if we are not associated
- * and we are not associating / authenticating
- */
- if (ieee->state != IEEE80211_NOLINK)
- return;
-
- if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
- return;
-
- if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
- return;
-
- if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
- /* if the user specified the AP MAC, we need also the essid
- * This could be obtained by beacons or, if the network does not
- * broadcast it, it can be put manually.
- */
- apset = ieee->wap_set;
- ssidset = ieee->ssid_set;
- ssidbroad = !(net->ssid_len == 0 || net->ssid[0] == '\0');
- apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN) == 0);
-
- if (ieee->current_network.ssid_len != net->ssid_len)
- ssidmatch = 0;
- else
- ssidmatch = (0 == strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
-
- /* if the user set the AP check if match.
- * if the network does not broadcast essid we check the user
- * supplied ANY essid
- * if the network does broadcast and the user does not set essid
- * it is OK
- * if the network does broadcast and the user did set essid
- * chech if essid match
- * (apset && apmatch && ((ssidset && ssidbroad && ssidmatch) ||
- * (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
- * if the ap is not set, check that the user set the bssid and
- * the network does broadcast and that those two bssid matches
- * (!apset && ssidset && ssidbroad && ssidmatch)
- */
- if ((apset && apmatch && ((ssidset && ssidbroad && ssidmatch) ||
- (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
- (!apset && ssidset && ssidbroad && ssidmatch)) {
- /* if the essid is hidden replace it with the
- * essid provided by the user.
- */
- if (!ssidbroad) {
- strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
- tmp_ssid_len = ieee->current_network.ssid_len;
- }
- memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
-
- if (!ssidbroad) {
- strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
- ieee->current_network.ssid_len = tmp_ssid_len;
- }
- printk(KERN_INFO"Linking with %s: channel is %d\n", ieee->current_network.ssid, ieee->current_network.channel);
-
- if (ieee->iw_mode == IW_MODE_INFRA) {
- ieee->state = IEEE80211_ASSOCIATING;
- ieee->beinretry = false;
- queue_work(ieee->wq, &ieee->associate_procedure_wq);
- } else {
- if (ieee80211_is_54g(&ieee->current_network) &&
- (ieee->modulation & IEEE80211_OFDM_MODULATION)) {
- ieee->rate = 540;
- printk(KERN_INFO"Using G rates\n");
- } else {
- ieee->rate = 110;
- printk(KERN_INFO"Using B rates\n");
- }
- ieee->state = IEEE80211_LINKED;
- ieee->beinretry = false;
- }
- }
- }
-}
-
-void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
-{
- unsigned long flags;
- struct ieee80211_network *target;
-
- spin_lock_irqsave(&ieee->lock, flags);
- list_for_each_entry(target, &ieee->network_list, list) {
- /* if the state become different that NOLINK means
- * we had found what we are searching for
- */
- if (ieee->state != IEEE80211_NOLINK)
- break;
-
- if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
- ieee80211_softmac_new_net(ieee, target);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
-{
- struct ieee80211_authentication *a;
- u8 *t;
- if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
- IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
- return 0xcafe;
- }
- *challenge = NULL;
- a = (struct ieee80211_authentication *) skb->data;
- if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) {
- t = skb->data + sizeof(struct ieee80211_authentication);
-
- if (*(t++) == MFIE_TYPE_CHALLENGE) {
- *chlen = *(t++);
- *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
- if (!*challenge)
- return -ENOMEM;
- }
- }
- return cpu_to_le16(a->status);
-}
-
-static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
-{
- struct ieee80211_authentication *a;
-
- if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
- IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n", skb->len);
- return -1;
- }
- a = (struct ieee80211_authentication *) skb->data;
-
- memcpy(dest, a->header.addr2, ETH_ALEN);
-
- if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
- return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
-
- return WLAN_STATUS_SUCCESS;
-}
-
-static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb,
- u8 *src)
-{
- u8 *tag;
- u8 *skbend;
- u8 *ssid = NULL;
- u8 ssidlen = 0;
-
- struct ieee80211_hdr_3addr *header =
- (struct ieee80211_hdr_3addr *) skb->data;
-
- if (skb->len < sizeof(struct ieee80211_hdr_3addr))
- return -1; /* corrupted */
-
- memcpy(src, header->addr2, ETH_ALEN);
-
- skbend = (u8 *)skb->data + skb->len;
-
- tag = skb->data + sizeof(struct ieee80211_hdr_3addr);
-
- while (tag+1 < skbend) {
- if (*tag == 0) {
- ssid = tag+2;
- ssidlen = *(tag+1);
- break;
- }
- tag++; /* point to the len field */
- tag = tag + *(tag); /* point to the last data byte of the tag */
- tag++; /* point to the next tag */
- }
-
- if (ssidlen == 0)
- return 1;
-
- if (!ssid)
- return 1; /* ssid not found in tagged param */
-
- return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
-
-}
-
-static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
-{
- struct ieee80211_assoc_request_frame *a;
-
- if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
- sizeof(struct ieee80211_info_element))) {
-
- IEEE80211_DEBUG_MGMT("invalid len in auth request:%d\n", skb->len);
- return -1;
- }
-
- a = (struct ieee80211_assoc_request_frame *) skb->data;
-
- memcpy(dest, a->header.addr2, ETH_ALEN);
-
- return 0;
-}
-
-static inline u16 assoc_parse(struct sk_buff *skb, int *aid)
-{
- struct ieee80211_assoc_response_frame *a;
- if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) {
- IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
- return 0xcafe;
- }
-
- a = (struct ieee80211_assoc_response_frame *) skb->data;
- *aid = le16_to_cpu(a->aid) & 0x3fff;
- return le16_to_cpu(a->status);
-}
-
-static inline void ieee80211_rx_probe_rq(struct ieee80211_device *ieee,
- struct sk_buff *skb)
-{
- u8 dest[ETH_ALEN];
-
- ieee->softmac_stats.rx_probe_rq++;
- if (probe_rq_parse(ieee, skb, dest)) {
- ieee->softmac_stats.tx_probe_rs++;
- ieee80211_resp_to_probe(ieee, dest);
- }
-}
-
-inline void ieee80211_rx_auth_rq(struct ieee80211_device *ieee,
- struct sk_buff *skb)
-{
- u8 dest[ETH_ALEN];
- int status;
- ieee->softmac_stats.rx_auth_rq++;
-
- status = auth_rq_parse(skb, dest);
- if (status != -1)
- ieee80211_resp_to_auth(ieee, status, dest);
-}
-
-inline void
-ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
-{
-
- u8 dest[ETH_ALEN];
-
- ieee->softmac_stats.rx_ass_rq++;
- if (assoc_rq_parse(skb, dest) != -1)
- ieee80211_resp_to_assoc_rq(ieee, dest);
-
-
- printk(KERN_INFO"New client associated: %pM\n", dest);
-}
-
-void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
-{
- struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
-
- if (buf)
- softmac_ps_mgmt_xmit(buf, ieee);
-}
-
-static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
- u32 *time_l)
-{
- int timeout = 0;
-
- u8 dtim;
- dtim = ieee->current_network.dtim_data;
-
- if (!(dtim & IEEE80211_DTIM_VALID))
- return 0;
- else
- timeout = ieee->current_network.beacon_interval;
-
- ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
-
- if (dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST) & ieee->ps))
- return 2;
-
- if (!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
- return 0;
-
- if (!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
- return 0;
-
- if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) &&
- (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
- return 0;
-
- if (time_l) {
- *time_l = ieee->current_network.last_dtim_sta_time[0]
- + MSECS((ieee->current_network.beacon_interval));
- }
-
- if (time_h) {
- *time_h = ieee->current_network.last_dtim_sta_time[1];
- if (time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
- *time_h += 1;
- }
-
- return 1;
-}
-
-static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
-{
-
- u32 th, tl;
- short sleep;
-
- unsigned long flags, flags2;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if ((ieee->ps == IEEE80211_PS_DISABLED ||
- ieee->iw_mode != IW_MODE_INFRA ||
- ieee->state != IEEE80211_LINKED)) {
-
- /* #warning CHECK_LOCK_HERE */
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-
- ieee80211_sta_wakeup(ieee, 1);
-
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
-
- sleep = ieee80211_sta_ps_sleep(ieee, &th, &tl);
- /* 2 wake, 1 sleep, 0 do nothing */
- if (sleep == 0)
- goto out;
-
- if (sleep == 1) {
- if (ieee->sta_sleep == 1)
- ieee->enter_sleep_state(ieee->dev, th, tl);
-
- else if (ieee->sta_sleep == 0) {
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
- if (ieee->ps_is_queue_empty(ieee->dev)) {
- ieee->sta_sleep = 2;
-
- ieee->ps_request_tx_ack(ieee->dev);
-
- ieee80211_sta_ps_send_null_frame(ieee, 1);
-
- ieee->ps_th = th;
- ieee->ps_tl = tl;
- }
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
- } else if (sleep == 2) {
- /* #warning CHECK_LOCK_HERE */
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-
- ieee80211_sta_wakeup(ieee, 1);
-
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
-out:
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
-{
- if (ieee->sta_sleep == 0) {
- if (nl) {
- ieee->ps_request_tx_ack(ieee->dev);
- ieee80211_sta_ps_send_null_frame(ieee, 0);
- }
- return;
- }
-
- if (ieee->sta_sleep == 1)
- ieee->sta_wake_up(ieee->dev);
-
- ieee->sta_sleep = 0;
-
- if (nl) {
- ieee->ps_request_tx_ack(ieee->dev);
- ieee80211_sta_ps_send_null_frame(ieee, 0);
- }
-}
-
-void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
-{
- unsigned long flags, flags2;
-
- spin_lock_irqsave(&ieee->lock, flags);
- if (ieee->sta_sleep == 2) {
- /* Null frame with PS bit set */
- if (success) {
- ieee->sta_sleep = 1;
- ieee->enter_sleep_state(ieee->dev, ieee->ps_th, ieee->ps_tl);
- }
- /* if the card report not success we can't be sure the AP
- * has not RXed so we can't assume the AP believe us awake
- */
- } else {
- if ((ieee->sta_sleep == 0) && !success) {
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
- ieee80211_sta_ps_send_null_frame(ieee, 0);
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-inline int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee,
- struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats,
- u16 type, u16 stype)
-{
- struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
- u16 errcode;
- u8 *challenge = NULL;
- int chlen = 0;
- int aid = 0;
- struct ieee80211_assoc_response_frame *assoc_resp;
- struct ieee80211_info_element *info_element;
-
- if (!ieee->proto_started)
- return 0;
-
- if (ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
- ieee->iw_mode == IW_MODE_INFRA &&
- ieee->state == IEEE80211_LINKED))
-
- tasklet_schedule(&ieee->ps_task);
-
- if (WLAN_FC_GET_STYPE(header->frame_control) != IEEE80211_STYPE_PROBE_RESP &&
- WLAN_FC_GET_STYPE(header->frame_control) != IEEE80211_STYPE_BEACON)
- ieee->last_rx_ps_time = jiffies;
-
- switch (WLAN_FC_GET_STYPE(header->frame_control)) {
- case IEEE80211_STYPE_ASSOC_RESP:
- case IEEE80211_STYPE_REASSOC_RESP:
- IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
- if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
- ieee->iw_mode == IW_MODE_INFRA) {
- errcode = assoc_parse(skb, &aid);
- if (0 == errcode) {
- u16 left;
-
- ieee->state = IEEE80211_LINKED;
- ieee->assoc_id = aid;
- ieee->softmac_stats.rx_ass_ok++;
- /* card type is 8187 */
- if (1 == rx_stats->nic_type)
- goto associate_complete;
-
- assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
- info_element = &assoc_resp->info_element;
- left = skb->len - ((void *)info_element - (void *)assoc_resp);
-
- while (left >= sizeof(struct ieee80211_info_element_hdr)) {
- if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
- printk(KERN_WARNING "[re]associate response error!");
- return 1;
- }
- switch (info_element->id) {
- case MFIE_TYPE_GENERIC:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element->len);
- if (info_element->len >= 8 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0xf2 &&
- info_element->data[3] == 0x02 &&
- info_element->data[4] == 0x01) {
- /* Not care about version at present.
- * WMM Parameter Element.
- */
- memcpy(ieee->current_network.wmm_param, (u8 *)(info_element->data\
- + 8), (info_element->len - 8));
-
- if (((ieee->current_network.wmm_info^info_element->data[6])& \
- 0x0f) || (!ieee->init_wmmparam_flag)) {
- /* refresh parameter element for current network
- * update the register parameter for hardware.
- */
- ieee->init_wmmparam_flag = 1;
- queue_work(ieee->wq, &ieee->wmm_param_update_wq);
- }
- /* update info_element for current network */
- ieee->current_network.wmm_info = info_element->data[6];
- }
- break;
- default:
- /* nothing to do at present!!! */
- break;
- }
-
- left -= sizeof(struct ieee80211_info_element_hdr) +
- info_element->len;
- info_element = (struct ieee80211_info_element *)
- &info_element->data[info_element->len];
- }
- /* legacy AP, reset the AC_xx_param register */
- if (!ieee->init_wmmparam_flag) {
- queue_work(ieee->wq, &ieee->wmm_param_update_wq);
- ieee->init_wmmparam_flag = 1; /* indicate AC_xx_param upated since last associate */
- }
-associate_complete:
- ieee80211_associate_complete(ieee);
- } else {
- ieee->softmac_stats.rx_ass_err++;
- IEEE80211_DEBUG_MGMT(
- "Association response status code 0x%x\n",
- errcode);
- ieee80211_associate_abort(ieee);
- }
- }
- break;
- case IEEE80211_STYPE_ASSOC_REQ:
- case IEEE80211_STYPE_REASSOC_REQ:
- if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- ieee->iw_mode == IW_MODE_MASTER)
-
- ieee80211_rx_assoc_rq(ieee, skb);
- break;
- case IEEE80211_STYPE_AUTH:
- if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
- if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
- ieee->iw_mode == IW_MODE_INFRA){
- IEEE80211_DEBUG_MGMT("Received authentication response");
-
- errcode = auth_parse(skb, &challenge, &chlen);
- if (0 == errcode) {
- if (ieee->open_wep || !challenge) {
- ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
- ieee->softmac_stats.rx_auth_rs_ok++;
-
- ieee80211_associate_step2(ieee);
- } else {
- ieee80211_rtl_auth_challenge(ieee, challenge, chlen);
- }
- } else {
- ieee->softmac_stats.rx_auth_rs_err++;
- IEEE80211_DEBUG_MGMT("Authentication response status code 0x%x", errcode);
- ieee80211_associate_abort(ieee);
- }
-
- } else if (ieee->iw_mode == IW_MODE_MASTER) {
- ieee80211_rx_auth_rq(ieee, skb);
- }
- }
- break;
- case IEEE80211_STYPE_PROBE_REQ:
- if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
- ((ieee->iw_mode == IW_MODE_ADHOC ||
- ieee->iw_mode == IW_MODE_MASTER) &&
- ieee->state == IEEE80211_LINKED))
-
- ieee80211_rx_probe_rq(ieee, skb);
- break;
- case IEEE80211_STYPE_DISASSOC:
- case IEEE80211_STYPE_DEAUTH:
- /* FIXME for now repeat all the association procedure
- * both for disassociation and deauthentication
- */
- if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- (ieee->state == IEEE80211_LINKED) &&
- (ieee->iw_mode == IW_MODE_INFRA) &&
- (!memcmp(header->addr2, ieee->current_network.bssid, ETH_ALEN))) {
- ieee->state = IEEE80211_ASSOCIATING;
- ieee->softmac_stats.reassoc++;
-
- queue_work(ieee->wq, &ieee->associate_procedure_wq);
- }
- break;
- default:
- return -1;
- break;
- }
- return 0;
-}
-
-/* following are for a simpler TX queue management.
- * Instead of using netif_[stop/wake]_queue the driver
- * will uses these two function (plus a reset one), that
- * will internally uses the kernel netif_* and takes
- * care of the ieee802.11 fragmentation.
- * So the driver receives a fragment per time and might
- * call the stop function when it want without take care
- * to have enough room to TX an entire packet.
- * This might be useful if each fragment need it's own
- * descriptor, thus just keep a total free memory > than
- * the max fragmentation threshold is not enough.. If the
- * ieee802.11 stack passed a TXB struct then you needed
- * to keep N free descriptors where
- * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
- * In this way you need just one and the 802.11 stack
- * will take care of buffering fragments and pass them to
- * to the driver later, when it wakes the queue.
- */
-
-void ieee80211_softmac_xmit(struct ieee80211_txb *txb,
- struct ieee80211_device *ieee)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- /* called with 2nd parm 0, no tx mgmt lock required */
- ieee80211_sta_wakeup(ieee, 0);
-
- for (i = 0; i < txb->nr_frags; i++) {
- if (ieee->queue_stop) {
- ieee->tx_pending.txb = txb;
- ieee->tx_pending.frag = i;
- goto exit;
- } else {
- ieee->softmac_data_hard_start_xmit(
- txb->fragments[i],
- ieee->dev, ieee->rate);
- ieee->stats.tx_packets++;
- ieee->stats.tx_bytes += txb->fragments[i]->len;
- ieee->dev->trans_start = jiffies;
- }
- }
-
- ieee80211_txb_free(txb);
-
- exit:
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-/* called with ieee->lock acquired */
-static void ieee80211_resume_tx(struct ieee80211_device *ieee)
-{
- int i;
- for (i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
-
- if (ieee->queue_stop) {
- ieee->tx_pending.frag = i;
- return;
- } else {
- ieee->softmac_data_hard_start_xmit(
- ieee->tx_pending.txb->fragments[i],
- ieee->dev, ieee->rate);
- ieee->stats.tx_packets++;
- ieee->dev->trans_start = jiffies;
- }
- }
-
- ieee80211_txb_free(ieee->tx_pending.txb);
- ieee->tx_pending.txb = NULL;
-}
-
-void ieee80211_reset_queue(struct ieee80211_device *ieee)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->lock, flags);
- init_mgmt_queue(ieee);
- if (ieee->tx_pending.txb) {
- ieee80211_txb_free(ieee->tx_pending.txb);
- ieee->tx_pending.txb = NULL;
- }
- ieee->queue_stop = 0;
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
-{
- unsigned long flags;
- struct sk_buff *skb;
- struct ieee80211_hdr_3addr *header;
-
- spin_lock_irqsave(&ieee->lock, flags);
- if (!ieee->queue_stop)
- goto exit;
-
- ieee->queue_stop = 0;
-
- if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) {
- while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))) {
- header = (struct ieee80211_hdr_3addr *) skb->data;
-
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
- dev_kfree_skb_any(skb);
- }
- }
- if (!ieee->queue_stop && ieee->tx_pending.txb)
- ieee80211_resume_tx(ieee);
-
- if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) {
- ieee->softmac_stats.swtxawake++;
- netif_wake_queue(ieee->dev);
- }
-exit:
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
-{
- if (!netif_queue_stopped(ieee->dev)) {
- netif_stop_queue(ieee->dev);
- ieee->softmac_stats.swtxstop++;
- }
- ieee->queue_stop = 1;
-}
-
-inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
-{
- random_ether_addr(ieee->current_network.bssid);
-}
-
-/* called in user context only */
-void ieee80211_start_master_bss(struct ieee80211_device *ieee)
-{
- ieee->assoc_id = 1;
-
- if (ieee->current_network.ssid_len == 0) {
- strncpy(ieee->current_network.ssid,
- IEEE80211_DEFAULT_TX_ESSID,
- IW_ESSID_MAX_SIZE);
-
- ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
- ieee->ssid_set = 1;
- }
-
- memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
-
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- ieee->state = IEEE80211_LINKED;
- ieee->link_change(ieee->dev);
- notify_wx_assoc_event(ieee);
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- netif_carrier_on(ieee->dev);
-}
-
-static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
-{
- if (ieee->raw_tx) {
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- netif_carrier_on(ieee->dev);
- }
-}
-
-static void ieee80211_start_ibss_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_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.
- * Anyway some most set operations set a flag to speed-up
- * (abort) this wq (when syncro scanning) before sleeping
- * on the semaphore
- */
-
- down(&ieee->wx_sem);
-
- if (ieee->current_network.ssid_len == 0) {
- strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID);
- ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
- ieee->ssid_set = 1;
- }
-
- /* check if we have this cell in our network list */
- ieee80211_softmac_check_all_nets(ieee);
-
- if (ieee->state == IEEE80211_NOLINK)
- ieee->current_network.channel = 10;
- /* if not then the state is not linked. Maybe the user switched to
- * ad-hoc mode just after being in monitor mode, or just after
- * being very few time in managed mode (so the card have had no
- * time to scan all the chans..) or we have just run up the iface
- * after setting ad-hoc mode. So we have to give another try..
- * Here, in ibss mode, should be safe to do this without extra care
- * (in bss mode we had to make sure no-one tried to associate when
- * we had just checked the ieee->state and we was going to start the
- * scan) because in ibss mode the ieee80211_new_net function, when
- * finds a good net, just set the ieee->state to IEEE80211_LINKED,
- * so, at worst, we waste a bit of time to initiate an unneeded syncro
- * scan, that will stop at the first round because it sees the state
- * associated.
- */
- if (ieee->state == IEEE80211_NOLINK)
- ieee80211_start_scan_syncro(ieee);
-
- /* the network definitively is not here.. create a new cell */
- if (ieee->state == IEEE80211_NOLINK) {
- printk("creating new IBSS cell\n");
- if (!ieee->wap_set)
- ieee80211_randomize_cell(ieee);
-
- if (ieee->modulation & IEEE80211_CCK_MODULATION) {
- ieee->current_network.rates_len = 4;
-
- ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
- ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
- ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
- ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
-
- } else
- ieee->current_network.rates_len = 0;
-
- if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
- ieee->current_network.rates_ex_len = 8;
-
- ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
- ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
- ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
- ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
- ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
- ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
- ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
- ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
-
- ieee->rate = 540;
- } else {
- ieee->current_network.rates_ex_len = 0;
- ieee->rate = 110;
- }
-
- /* By default, WMM function will be disabled in IBSS mode */
- ieee->current_network.QoS_Enable = 0;
-
- ieee->current_network.atim_window = 0;
- ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
- if (ieee->short_slot)
- ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
- }
-
- ieee->state = IEEE80211_LINKED;
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- ieee->link_change(ieee->dev);
-
- notify_wx_assoc_event(ieee);
-
- ieee80211_start_send_beacons(ieee);
- printk(KERN_WARNING "after sending beacon packet!\n");
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- netif_carrier_on(ieee->dev);
-
- up(&ieee->wx_sem);
-}
-
-inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
-{
- queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 100);
-}
-
-/* this is called only in user context, with wx_sem held */
-void ieee80211_start_bss(struct ieee80211_device *ieee)
-{
- unsigned long flags;
- /* Ref: 802.11d 11.1.3.3
- * STA shall not start a BSS unless properly formed Beacon frame
- * including a Country IE.
- */
- if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) {
- if (!ieee->bGlobalDomain)
- return;
- }
- /* check if we have already found the net we are interested in (if any).
- * if not (we are disassociated and we are not
- * in associating / authenticating phase) start the background scanning.
- */
- ieee80211_softmac_check_all_nets(ieee);
-
- /* ensure no-one start an associating process (thus setting
- * the ieee->state to ieee80211_ASSOCIATING) while we
- * have just cheked it and we are going to enable scan.
- * The ieee80211_new_net function is always called with
- * lock held (from both ieee80211_softmac_check_all_nets and
- * the rx path), so we cannot be in the middle of such function
- */
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->state == IEEE80211_NOLINK) {
- ieee->actscanning = true;
- ieee80211_rtl_start_scan(ieee);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-/* called only in userspace context */
-void ieee80211_disassociate(struct ieee80211_device *ieee)
-{
- netif_carrier_off(ieee->dev);
-
- if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
- ieee80211_reset_queue(ieee);
-
- if (ieee->data_hard_stop)
- ieee->data_hard_stop(ieee->dev);
-
- if (IS_DOT11D_ENABLE(ieee))
- Dot11d_Reset(ieee);
-
- ieee->link_change(ieee->dev);
- if (ieee->state == IEEE80211_LINKED)
- notify_wx_assoc_event(ieee);
- ieee->state = IEEE80211_NOLINK;
-
-}
-static void ieee80211_associate_retry_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
- unsigned long flags;
- down(&ieee->wx_sem);
- if (!ieee->proto_started)
- goto exit;
- if (ieee->state != IEEE80211_ASSOCIATING_RETRY)
- goto exit;
- /* until we do not set the state to IEEE80211_NOLINK
- * there are no possibility to have someone else trying
- * to start an association procedure (we get here with
- * ieee->state = IEEE80211_ASSOCIATING).
- * When we set the state to IEEE80211_NOLINK it is possible
- * that the RX path run an attempt to associate, but
- * both ieee80211_softmac_check_all_nets and the
- * RX path works with ieee->lock held so there are no
- * problems. If we are still disassociated then start a scan.
- * the lock here is necessary to ensure no one try to start
- * an association procedure when we have just checked the
- * state and we are going to start the scan.
- */
- ieee->state = IEEE80211_NOLINK;
- ieee->beinretry = true;
- ieee80211_softmac_check_all_nets(ieee);
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->state == IEEE80211_NOLINK) {
- ieee->beinretry = false;
- ieee->actscanning = true;
- ieee80211_rtl_start_scan(ieee);
- }
- if (ieee->state == IEEE80211_NOLINK)
- notify_wx_assoc_event(ieee);
- spin_unlock_irqrestore(&ieee->lock, flags);
-
-exit:
- up(&ieee->wx_sem);
-}
-
-struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
-{
- u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
- struct sk_buff *skb = NULL;
- struct ieee80211_probe_response *b;
-
- skb = ieee80211_probe_resp(ieee, broadcast_addr);
- if (!skb)
- return NULL;
-
- b = (struct ieee80211_probe_response *) skb->data;
- b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
-
- return skb;
-}
-
-struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
- struct ieee80211_probe_response *b;
-
- skb = ieee80211_get_beacon_(ieee);
- if (!skb)
- return NULL;
-
- b = (struct ieee80211_probe_response *) skb->data;
- b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- return skb;
-}
-
-void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
-{
- ieee->sync_scan_hurryup = 1;
- down(&ieee->wx_sem);
- ieee80211_stop_protocol(ieee);
- up(&ieee->wx_sem);
-}
-
-void ieee80211_stop_protocol(struct ieee80211_device *ieee)
-{
- if (!ieee->proto_started)
- return;
-
- ieee->proto_started = 0;
-
- ieee80211_stop_send_beacons(ieee);
- if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_LINKED))
- SendDisassociation(ieee, NULL, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
-
- del_timer_sync(&ieee->associate_timer);
- cancel_delayed_work(&ieee->associate_retry_wq);
- cancel_delayed_work(&ieee->start_ibss_wq);
- ieee80211_stop_scan(ieee);
-
- ieee80211_disassociate(ieee);
-}
-
-void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
-{
- ieee->sync_scan_hurryup = 0;
- down(&ieee->wx_sem);
- ieee80211_start_protocol(ieee);
- up(&ieee->wx_sem);
-}
-
-void ieee80211_start_protocol(struct ieee80211_device *ieee)
-{
- short ch = 0;
- int i = 0;
-
- if (ieee->proto_started)
- return;
-
- ieee->proto_started = 1;
-
- if (ieee->current_network.channel == 0) {
- do {
- ch++;
- if (ch > MAX_CHANNEL_NUMBER)
- return; /* no channel found */
-
- } while (!GET_DOT11D_INFO(ieee)->channel_map[ch]);
-
- ieee->current_network.channel = ch;
- }
-
- if (ieee->current_network.beacon_interval == 0)
- ieee->current_network.beacon_interval = 100;
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
- for (i = 0; i < 17; i++) {
- ieee->last_rxseq_num[i] = -1;
- ieee->last_rxfrag_num[i] = -1;
- ieee->last_packet_time[i] = 0;
- }
-
- ieee->init_wmmparam_flag = 0; /* reinitialize AC_xx_PARAM registers. */
-
- /* if the user set the MAC of the ad-hoc cell and then
- * switch to managed mode, shall we make sure that association
- * attempts does not fail just because the user provide the essid
- * and the nic is still checking for the AP MAC ??
- */
- switch (ieee->iw_mode) {
- case IW_MODE_AUTO:
- ieee->iw_mode = IW_MODE_INFRA;
- /* not set break here intentionly */
- case IW_MODE_INFRA:
- ieee80211_start_bss(ieee);
- break;
-
- case IW_MODE_ADHOC:
- ieee80211_start_ibss(ieee);
- break;
-
- case IW_MODE_MASTER:
- ieee80211_start_master_bss(ieee);
- break;
-
- case IW_MODE_MONITOR:
- ieee80211_start_monitor_mode(ieee);
- break;
-
- default:
- ieee->iw_mode = IW_MODE_INFRA;
- ieee80211_start_bss(ieee);
- break;
- }
-}
-
-#define DRV_NAME "Ieee80211"
-void ieee80211_softmac_init(struct ieee80211_device *ieee)
-{
- int i;
- memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
-
- ieee->state = IEEE80211_NOLINK;
- ieee->sync_scan_hurryup = 0;
- for (i = 0; i < 5; i++)
- ieee->seq_ctrl[i] = 0;
-
- ieee->assoc_id = 0;
- ieee->queue_stop = 0;
- ieee->scanning = 0;
- ieee->softmac_features = 0; /* so IEEE2100-like driver are happy */
- ieee->wap_set = 0;
- ieee->ssid_set = 0;
- ieee->proto_started = 0;
- ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
- ieee->rate = 3;
- ieee->ps = IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST;
- ieee->sta_sleep = 0;
- ieee->bInactivePs = false;
- ieee->actscanning = false;
- ieee->ListenInterval = 2;
- ieee->NumRxDataInPeriod = 0;
- ieee->NumRxBcnInPeriod = 0;
- ieee->NumRxOkTotal = 0;
- ieee->NumRxUnicast = 0; /* for keep alive */
- ieee->beinretry = false;
- ieee->bHwRadioOff = false;
-
- init_mgmt_queue(ieee);
-
- ieee->tx_pending.txb = NULL;
-
- init_timer(&ieee->associate_timer);
- ieee->associate_timer.data = (unsigned long)ieee;
- ieee->associate_timer.function = ieee80211_associate_abort_cb;
-
- init_timer(&ieee->beacon_timer);
- ieee->beacon_timer.data = (unsigned long) ieee;
- ieee->beacon_timer.function = ieee80211_send_beacon_cb;
-
- ieee->wq = create_workqueue(DRV_NAME);
-
- INIT_DELAYED_WORK(&ieee->start_ibss_wq, (void *) ieee80211_start_ibss_wq);
- INIT_WORK(&ieee->associate_complete_wq, (void *) ieee80211_associate_complete_wq);
- INIT_WORK(&ieee->associate_procedure_wq, (void *) ieee80211_associate_procedure_wq);
- INIT_DELAYED_WORK(&ieee->softmac_scan_wq, (void *) ieee80211_softmac_scan_wq);
- INIT_DELAYED_WORK(&ieee->associate_retry_wq, (void *) ieee80211_associate_retry_wq);
- INIT_WORK(&ieee->wx_sync_scan_wq, (void *) ieee80211_wx_sync_scan_wq);
-
- sema_init(&ieee->wx_sem, 1);
- sema_init(&ieee->scan_sem, 1);
-
- spin_lock_init(&ieee->mgmt_tx_lock);
- spin_lock_init(&ieee->beacon_lock);
-
- tasklet_init(&ieee->ps_task,
- (void(*)(unsigned long)) ieee80211_sta_ps,
- (unsigned long)ieee);
- ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
-}
-
-void ieee80211_softmac_free(struct ieee80211_device *ieee)
-{
- down(&ieee->wx_sem);
-
- del_timer_sync(&ieee->associate_timer);
- cancel_delayed_work(&ieee->associate_retry_wq);
-
- /* add for RF power on power of */
- cancel_delayed_work(&ieee->GPIOChangeRFWorkItem);
-
- destroy_workqueue(ieee->wq);
- kfree(ieee->pDot11dInfo);
- up(&ieee->wx_sem);
-}
-
-/* Start of WPA code. This is stolen from the ipw2200 driver */
-static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
-{
- /* This is called when wpa_supplicant loads and closes the driver
- * interface. */
- printk("%s WPA\n", value ? "enabling" : "disabling");
- ieee->wpa_enabled = value;
- return 0;
-}
-
-static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie,
- int wpa_ie_len)
-{
- /* make sure WPA is enabled */
- ieee80211_wpa_enable(ieee, 1);
-
- ieee80211_disassociate(ieee);
-}
-
-static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command,
- int reason)
-{
- int ret = 0;
-
- switch (command) {
- case IEEE_MLME_STA_DEAUTH:
- /* silently ignore */
- break;
-
- case IEEE_MLME_STA_DISASSOC:
- ieee80211_disassociate(ieee);
- break;
-
- default:
- printk("Unknown MLME request: %d\n", command);
- ret = -EOPNOTSUPP;
- }
-
- return ret;
-}
-
-static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
- struct ieee_param *param, int plen)
-{
- u8 *buf;
-
- if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
- (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
- return -EINVAL;
-
- if (param->u.wpa_ie.len) {
- buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
- GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = buf;
- ieee->wpa_ie_len = param->u.wpa_ie.len;
- } else {
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = NULL;
- ieee->wpa_ie_len = 0;
- }
-
- ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
- return 0;
-}
-
-#define AUTH_ALG_OPEN_SYSTEM 0x1
-#define AUTH_ALG_SHARED_KEY 0x2
-
-static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
-{
- struct ieee80211_security sec = {
- .flags = SEC_AUTH_MODE,
- };
- int ret = 0;
-
- if (value & AUTH_ALG_SHARED_KEY) {
- sec.auth_mode = WLAN_AUTH_SHARED_KEY;
- ieee->open_wep = 0;
- } else {
- sec.auth_mode = WLAN_AUTH_OPEN;
- ieee->open_wep = 1;
- }
-
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
- else
- ret = -EOPNOTSUPP;
-
- return ret;
-}
-
-static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name,
- u32 value)
-{
- int ret = 0;
- unsigned long flags;
-
- switch (name) {
- case IEEE_PARAM_WPA_ENABLED:
- ret = ieee80211_wpa_enable(ieee, value);
- break;
-
- case IEEE_PARAM_TKIP_COUNTERMEASURES:
- ieee->tkip_countermeasures = value;
- break;
-
- case IEEE_PARAM_DROP_UNENCRYPTED: {
- /* HACK:
- *
- * wpa_supplicant calls set_wpa_enabled when the driver
- * is loaded and unloaded, regardless of if WPA is being
- * used. No other calls are made which can be used to
- * determine if encryption will be used or not prior to
- * association being expected. If encryption is not being
- * used, drop_unencrypted is set to false, else true -- we
- * can use this to determine if the CAP_PRIVACY_ON bit should
- * be set.
- */
- struct ieee80211_security sec = {
- .flags = SEC_ENABLED,
- .enabled = value,
- };
- ieee->drop_unencrypted = value;
- /* We only change SEC_LEVEL for open mode. Others
- * are set by ipw_wpa_set_encryption.
- */
- if (!value) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_0;
- } else {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1;
- }
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
- break;
- }
-
- case IEEE_PARAM_PRIVACY_INVOKED:
- ieee->privacy_invoked = value;
- break;
- case IEEE_PARAM_AUTH_ALGS:
- ret = ieee80211_wpa_set_auth_algs(ieee, value);
- break;
- case IEEE_PARAM_IEEE_802_1X:
- ieee->ieee802_1x = value;
- break;
- case IEEE_PARAM_WPAX_SELECT:
- spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
- ieee->wpax_type_set = 1;
- ieee->wpax_type_notify = value;
- spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
- break;
- default:
- printk("Unknown WPA param: %d\n", name);
- ret = -EOPNOTSUPP;
- }
-
- return ret;
-}
-
-/* implementation borrowed from hostap driver */
-
-static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
- struct ieee_param *param, int param_len)
-{
- int ret = 0;
-
- struct ieee80211_crypto_ops *ops;
- struct ieee80211_crypt_data **crypt;
-
- struct ieee80211_security sec = {
- .flags = 0,
- };
-
- param->u.crypt.err = 0;
- param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
-
- if (param_len !=
- (int) ((char *) param->u.crypt.key - (char *) param) +
- param->u.crypt.key_len) {
- printk("Len mismatch %d, %d\n", param_len,
- param->u.crypt.key_len);
- return -EINVAL;
- }
- if (is_broadcast_ether_addr(param->sta_addr)) {
- if (param->u.crypt.idx >= WEP_KEYS)
- return -EINVAL;
- crypt = &ieee->crypt[param->u.crypt.idx];
- } else {
- return -EINVAL;
- }
-
- if (strcmp(param->u.crypt.alg, "none") == 0) {
- if (crypt) {
- sec.enabled = 0;
- /* FIXME FIXME */
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_ENABLED | SEC_LEVEL;
- ieee80211_crypt_delayed_deinit(ieee, crypt);
- }
- goto done;
- }
- sec.enabled = 1;
- /* FIXME FIXME */
- sec.flags |= SEC_ENABLED;
-
- /* IPW HW cannot build TKIP MIC, host decryption still needed. */
- if (!(ieee->host_encrypt || ieee->host_decrypt) &&
- strcmp(param->u.crypt.alg, "TKIP"))
- goto skip_host_crypt;
-
- ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
- ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
- ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
- ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- if (ops == NULL) {
- printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
- param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
- ret = -EINVAL;
- goto done;
- }
-
- if (*crypt == NULL || (*crypt)->ops != ops) {
- struct ieee80211_crypt_data *new_crypt;
-
- ieee80211_crypt_delayed_deinit(ieee, crypt);
-
- new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
- if (new_crypt == NULL) {
- ret = -ENOMEM;
- goto done;
- }
- memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
- new_crypt->ops = ops;
- if (new_crypt->ops)
- new_crypt->priv =
- new_crypt->ops->init(param->u.crypt.idx);
-
- if (new_crypt->priv == NULL) {
- kfree(new_crypt);
- param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
- ret = -EINVAL;
- goto done;
- }
-
- *crypt = new_crypt;
- }
-
- if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
- (*crypt)->ops->set_key(param->u.crypt.key,
- param->u.crypt.key_len, param->u.crypt.seq,
- (*crypt)->priv) < 0) {
- printk("key setting failed\n");
- param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
- ret = -EINVAL;
- goto done;
- }
-
- skip_host_crypt:
- if (param->u.crypt.set_tx) {
- ieee->tx_keyidx = param->u.crypt.idx;
- sec.active_key = param->u.crypt.idx;
- sec.flags |= SEC_ACTIVE_KEY;
- } else
- sec.flags &= ~SEC_ACTIVE_KEY;
-
- if (param->u.crypt.alg != NULL) {
- memcpy(sec.keys[param->u.crypt.idx],
- param->u.crypt.key,
- param->u.crypt.key_len);
- sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
- sec.flags |= (1 << param->u.crypt.idx);
-
- if (strcmp(param->u.crypt.alg, "WEP") == 0) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1;
- } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_2;
- } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_3;
- }
- }
- done:
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
-
- /* Do not reset port if card is in Managed mode since resetting will
- * generate new IEEE 802.11 authentication which may end up in looping
- * with IEEE 802.1X. If your hardware requires a reset after WEP
- * configuration (for example... Prism2), implement the reset_port in
- * the callbacks structures used to initialize the 802.11 stack. */
- if (ieee->reset_on_keychange &&
- ieee->iw_mode != IW_MODE_INFRA &&
- ieee->reset_port &&
- ieee->reset_port(ieee->dev)) {
- printk("reset_port failed\n");
- param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
- return -EINVAL;
- }
-
- return ret;
-}
-
-int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee,
- struct iw_point *p)
-{
- struct ieee_param *param;
- int ret = 0;
-
- down(&ieee->wx_sem);
-
- if (p->length < sizeof(struct ieee_param) || !p->pointer) {
- ret = -EINVAL;
- goto out;
- }
-
- param = memdup_user(p->pointer, p->length);
- if (IS_ERR(param)) {
- ret = PTR_ERR(param);
- goto out;
- }
-
- switch (param->cmd) {
- case IEEE_CMD_SET_WPA_PARAM:
- ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
- param->u.wpa_param.value);
- break;
- case IEEE_CMD_SET_WPA_IE:
- ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
- break;
- case IEEE_CMD_SET_ENCRYPTION:
- ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
- break;
- case IEEE_CMD_MLME:
- ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
- param->u.mlme.reason_code);
- break;
- default:
- printk("Unknown WPA supplicant request: %d\n", param->cmd);
- ret = -EOPNOTSUPP;
- break;
- }
-
- if (ret == 0 && copy_to_user(p->pointer, param, p->length))
- ret = -EFAULT;
-
- kfree(param);
-out:
- up(&ieee->wx_sem);
-
- return ret;
-}
-
-void notify_wx_assoc_event(struct ieee80211_device *ieee)
-{
- union iwreq_data wrqu;
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- if (ieee->state == IEEE80211_LINKED)
- memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
- else
- memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
- wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
-}
+++ /dev/null
-/* IEEE 802.11 SoftMAC layer
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * Mostly extracted from the rtl8180-sa2400 driver for the
- * in-kernel generic ieee802.11 stack.
- *
- * Some pieces of code might be stolen from ipw2100 driver
- * copyright of who own it's copyright ;-)
- *
- * PS wx handler mostly stolen from hostap, copyright who
- * own it's copyright ;-)
- *
- * released under the GPL
- */
-
-
-#include <linux/etherdevice.h>
-
-#include "ieee80211.h"
-
-/* FIXME: add A freqs */
-
-const long ieee80211_wlan_frequencies[] = {
- 2412, 2417, 2422, 2427,
- 2432, 2437, 2442, 2447,
- 2452, 2457, 2462, 2467,
- 2472, 2484
-};
-
-
-int ieee80211_wx_set_freq(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *b)
-{
- int ret;
- struct iw_freq *fwrq = &wrqu->freq;
-// printk("in %s\n",__func__);
- down(&ieee->wx_sem);
-
- if (ieee->iw_mode == IW_MODE_INFRA) {
- ret = -EOPNOTSUPP;
- goto out;
- }
-
- /* if setting by freq convert to channel */
- if (fwrq->e == 1) {
- if ((fwrq->m >= (int) 2.412e8 &&
- fwrq->m <= (int) 2.487e8)) {
- int f = fwrq->m / 100000;
- int c = 0;
-
- while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
- c++;
-
- /* hack to fall through */
- fwrq->e = 0;
- fwrq->m = c + 1;
- }
- }
-
- if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) {
- ret = -EOPNOTSUPP;
- goto out;
-
- } else { /* Set the channel */
-
-
- ieee->current_network.channel = fwrq->m;
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
- if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
- if (ieee->state == IEEE80211_LINKED) {
- ieee80211_stop_send_beacons(ieee);
- ieee80211_start_send_beacons(ieee);
- }
- }
-
- ret = 0;
-out:
- up(&ieee->wx_sem);
- return ret;
-}
-
-
-int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *b)
-{
- struct iw_freq *fwrq = &wrqu->freq;
-
- if (ieee->current_network.channel == 0)
- return -1;
-
- fwrq->m = ieee->current_network.channel;
- fwrq->e = 0;
-
- return 0;
-}
-
-int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
- unsigned long flags;
-
- wrqu->ap_addr.sa_family = ARPHRD_ETHER;
-
- if (ieee->iw_mode == IW_MODE_MONITOR)
- return -1;
-
- /* We want avoid to give to the user inconsistent infos*/
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->state != IEEE80211_LINKED &&
- ieee->state != IEEE80211_LINKED_SCANNING &&
- ieee->wap_set == 0)
-
- memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
- else
- memcpy(wrqu->ap_addr.sa_data,
- ieee->current_network.bssid, ETH_ALEN);
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- return 0;
-}
-
-
-int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *awrq,
- char *extra)
-{
-
- int ret = 0;
- unsigned long flags;
-
- short ifup = ieee->proto_started;//dev->flags & IFF_UP;
- struct sockaddr *temp = (struct sockaddr *)awrq;
-
- //printk("=======Set WAP:");
- ieee->sync_scan_hurryup = 1;
-
- down(&ieee->wx_sem);
- /* use ifconfig hw ether */
- if (ieee->iw_mode == IW_MODE_MASTER) {
- ret = -1;
- goto out;
- }
-
- if (temp->sa_family != ARPHRD_ETHER) {
- ret = -EINVAL;
- goto out;
- }
-
- if (ifup)
- ieee80211_stop_protocol(ieee);
-
- /* just to avoid to give inconsistent infos in the
- * get wx method. not really needed otherwise
- */
- spin_lock_irqsave(&ieee->lock, flags);
-
- memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
- ieee->wap_set = !is_zero_ether_addr(temp->sa_data);
- //printk(" %x:%x:%x:%x:%x:%x\n", ieee->current_network.bssid[0],ieee->current_network.bssid[1],ieee->current_network.bssid[2],ieee->current_network.bssid[3],ieee->current_network.bssid[4],ieee->current_network.bssid[5]);
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- if (ifup)
- ieee80211_start_protocol(ieee);
-
-out:
- up(&ieee->wx_sem);
- return ret;
-}
-
-int ieee80211_wx_get_essid(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *b)
-{
- int len, ret = 0;
- unsigned long flags;
-
- if (ieee->iw_mode == IW_MODE_MONITOR)
- return -1;
-
- /* We want avoid to give to the user inconsistent infos*/
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->current_network.ssid[0] == '\0' ||
- ieee->current_network.ssid_len == 0){
- ret = -1;
- goto out;
- }
-
- if (ieee->state != IEEE80211_LINKED &&
- ieee->state != IEEE80211_LINKED_SCANNING &&
- ieee->ssid_set == 0){
- ret = -1;
- goto out;
- }
- len = ieee->current_network.ssid_len;
- wrqu->essid.length = len;
- strncpy(b, ieee->current_network.ssid, len);
- wrqu->essid.flags = 1;
-
-out:
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- return ret;
-
-}
-
-int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
-
- u32 target_rate = wrqu->bitrate.value;
-
- //added by lizhaoming for auto mode
- if (target_rate == -1)
- ieee->rate = 110;
- else
- ieee->rate = target_rate/100000;
-
- //FIXME: we might want to limit rate also in management protocols.
- return 0;
-}
-
-
-
-int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
-
- wrqu->bitrate.value = ieee->rate * 100000;
-
- return 0;
-}
-
-int ieee80211_wx_set_mode(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *b)
-{
-
- ieee->sync_scan_hurryup = 1;
-
- down(&ieee->wx_sem);
-
- if (wrqu->mode == ieee->iw_mode)
- goto out;
-
- if (wrqu->mode == IW_MODE_MONITOR)
- ieee->dev->type = ARPHRD_IEEE80211;
- else
- ieee->dev->type = ARPHRD_ETHER;
-
- if (!ieee->proto_started) {
- ieee->iw_mode = wrqu->mode;
- } else {
- ieee80211_stop_protocol(ieee);
- ieee->iw_mode = wrqu->mode;
- ieee80211_start_protocol(ieee);
- }
-
-out:
- up(&ieee->wx_sem);
- return 0;
-}
-
-
-void ieee80211_wx_sync_scan_wq(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
- short chan;
-
- chan = ieee->current_network.channel;
-
- if (ieee->data_hard_stop)
- ieee->data_hard_stop(ieee->dev);
-
- ieee80211_stop_send_beacons(ieee);
-
- ieee->state = IEEE80211_LINKED_SCANNING;
- ieee->link_change(ieee->dev);
-
- ieee80211_start_scan_syncro(ieee);
-
- ieee->set_chan(ieee->dev, chan);
-
- ieee->state = IEEE80211_LINKED;
- ieee->link_change(ieee->dev);
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
- ieee80211_start_send_beacons(ieee);
-
- //YJ,add,080828, In prevent of lossing ping packet during scanning
- //ieee80211_sta_ps_send_null_frame(ieee, false);
- //YJ,add,080828,end
-
- up(&ieee->wx_sem);
-
-}
-
-int ieee80211_wx_set_scan(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *b)
-{
- int ret = 0;
-
- down(&ieee->wx_sem);
-
- if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) {
- ret = -1;
- goto out;
- }
- //YJ,add,080828
- //In prevent of lossing ping packet during scanning
- //ieee80211_sta_ps_send_null_frame(ieee, true);
- //YJ,add,080828,end
-
- if (ieee->state == IEEE80211_LINKED) {
- queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
- /* intentionally forget to up sem */
- return 0;
- }
-
-out:
- up(&ieee->wx_sem);
- return ret;
-}
-
-int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *extra)
-{
-
- int ret = 0, len;
- short proto_started;
- unsigned long flags;
-
- ieee->sync_scan_hurryup = 1;
-
- down(&ieee->wx_sem);
-
- proto_started = ieee->proto_started;
-
- if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
- ret = -E2BIG;
- goto out;
- }
-
- if (ieee->iw_mode == IW_MODE_MONITOR) {
- ret = -1;
- goto out;
- }
-
- if (proto_started)
- ieee80211_stop_protocol(ieee);
-
- /* this is just to be sure that the GET wx callback
- * has consistent infos. not needed otherwise
- */
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (wrqu->essid.flags && wrqu->essid.length) {
-//YJ,modified,080819
- len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length) : IW_ESSID_MAX_SIZE;
- memset(ieee->current_network.ssid, 0, ieee->current_network.ssid_len); //YJ,add,080819
- strncpy(ieee->current_network.ssid, extra, len);
- ieee->current_network.ssid_len = len;
- ieee->ssid_set = 1;
-//YJ,modified,080819,end
-
- //YJ,add,080819,for hidden ap
- if (len == 0) {
- memset(ieee->current_network.bssid, 0, ETH_ALEN);
- ieee->current_network.capability = 0;
- }
- //YJ,add,080819,for hidden ap,end
- } else {
- ieee->ssid_set = 0;
- ieee->current_network.ssid[0] = '\0';
- ieee->current_network.ssid_len = 0;
- }
- //printk("==========set essid %s!\n",ieee->current_network.ssid);
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- if (proto_started)
- ieee80211_start_protocol(ieee);
-out:
- up(&ieee->wx_sem);
- return ret;
-}
-
-int ieee80211_wx_get_mode(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *b)
-{
-
- wrqu->mode = ieee->iw_mode;
- return 0;
-}
-
-int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
-
- int *parms = (int *)extra;
- int enable = (parms[0] > 0);
- short prev = ieee->raw_tx;
-
- down(&ieee->wx_sem);
-
- if (enable)
- ieee->raw_tx = 1;
- else
- ieee->raw_tx = 0;
-
- netdev_info(ieee->dev, "raw TX is %s\n",
- ieee->raw_tx ? "enabled" : "disabled");
-
- if (ieee->iw_mode == IW_MODE_MONITOR) {
- if (prev == 0 && ieee->raw_tx) {
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- netif_carrier_on(ieee->dev);
- }
-
- if (prev && ieee->raw_tx == 1)
- netif_carrier_off(ieee->dev);
- }
-
- up(&ieee->wx_sem);
-
- return 0;
-}
-
-int ieee80211_wx_get_name(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
- strlcpy(wrqu->name, "802.11", IFNAMSIZ);
- if (ieee->modulation & IEEE80211_CCK_MODULATION) {
- strlcat(wrqu->name, "b", IFNAMSIZ);
- if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- strlcat(wrqu->name, "/g", IFNAMSIZ);
- } else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- strlcat(wrqu->name, "g", IFNAMSIZ);
-
- if ((ieee->state == IEEE80211_LINKED) ||
- (ieee->state == IEEE80211_LINKED_SCANNING))
- strlcat(wrqu->name, " link", IFNAMSIZ);
- else if (ieee->state != IEEE80211_NOLINK)
- strlcat(wrqu->name, " .....", IFNAMSIZ);
-
-
- return 0;
-}
-
-
-/* this is mostly stolen from hostap */
-int ieee80211_wx_set_power(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
- int ret = 0;
-
- if ((!ieee->sta_wake_up) ||
- (!ieee->ps_request_tx_ack) ||
- (!ieee->enter_sleep_state) ||
- (!ieee->ps_is_queue_empty)) {
-
- printk("ERROR. PS mode tried to be use but driver missed a callback\n\n");
-
- return -1;
- }
-
- down(&ieee->wx_sem);
-
- if (wrqu->power.disabled) {
- ieee->ps = IEEE80211_PS_DISABLED;
-
- goto exit;
- }
- switch (wrqu->power.flags & IW_POWER_MODE) {
- case IW_POWER_UNICAST_R:
- ieee->ps = IEEE80211_PS_UNICAST;
-
- break;
- case IW_POWER_ALL_R:
- ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
- break;
-
- case IW_POWER_ON:
- ieee->ps = IEEE80211_PS_DISABLED;
- break;
-
- default:
- ret = -EINVAL;
- goto exit;
- }
-
- if (wrqu->power.flags & IW_POWER_TIMEOUT) {
-
- ieee->ps_timeout = wrqu->power.value / 1000;
- printk("Timeout %d\n", ieee->ps_timeout);
- }
-
- if (wrqu->power.flags & IW_POWER_PERIOD) {
-
- ret = -EOPNOTSUPP;
- goto exit;
- //wrq->value / 1024;
-
- }
-exit:
- up(&ieee->wx_sem);
- return ret;
-
-}
-
-/* this is stolen from hostap */
-int ieee80211_wx_get_power(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
- int ret = 0;
-
- down(&ieee->wx_sem);
-
- if (ieee->ps == IEEE80211_PS_DISABLED) {
- wrqu->power.disabled = 1;
- goto exit;
- }
-
- wrqu->power.disabled = 0;
-
-// if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
- wrqu->power.flags = IW_POWER_TIMEOUT;
- wrqu->power.value = ieee->ps_timeout * 1000;
-// } else {
-// ret = -EOPNOTSUPP;
-// goto exit;
- //wrqu->power.flags = IW_POWER_PERIOD;
- //wrqu->power.value = ieee->current_network.dtim_period *
- // ieee->current_network.beacon_interval * 1024;
-// }
-
-
- if (ieee->ps & IEEE80211_PS_MBCAST)
- wrqu->power.flags |= IW_POWER_ALL_R;
- else
- wrqu->power.flags |= IW_POWER_UNICAST_R;
-
-exit:
- up(&ieee->wx_sem);
- return ret;
-
-}
+++ /dev/null
-/******************************************************************************
-
- 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.
-
- 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., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- 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>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <asm/uaccess.h>
-#include <linux/if_vlan.h>
-
-#include "ieee80211.h"
-
-
-/*
-
-
-802.11 Data Frame
-
-
-802.11 frame_contorl for data frames - 2 bytes
- ,-----------------------------------------------------------------------------------------.
-bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
- |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
-val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
- |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
-desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
- | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
- '-----------------------------------------------------------------------------------------'
- /\
- |
-802.11 Data Frame |
- ,--------- 'ctrl' expands to >-----------'
- |
- ,--'---,-------------------------------------------------------------.
-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 non-data bytes `----.----'
- |
- .- 'Frame data' expands to <---------------------------'
- |
- V
- ,---------------------------------------------------.
-Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
- |------|------|---------|----------|------|---------|
-Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
- | DSAP | SSAP | | | | Packet |
- | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
- `-----------------------------------------| |
-Total: 8 non-data bytes `----.----'
- |
- .- 'IP Packet' expands, if WEP enabled, to <--'
- |
- V
- ,-----------------------.
-Bytes | 4 | 0-2296 | 4 |
- |-----|-----------|-----|
-Desc. | IV | Encrypted | ICV |
- | | IP Packet | |
- `-----------------------'
-Total: 8 non-data bytes
-
-
-802.3 Ethernet Data Frame
-
- ,-----------------------------------------.
-Bytes | 6 | 6 | 2 | Variable | 4 |
- |-------|-------|------|-----------|------|
-Desc. | Dest. | Source| Type | IP Packet | fcs |
- | MAC | MAC | | | |
- `-----------------------------------------'
-Total: 18 non-data bytes
-
-In the event that fragmentation is required, the incoming payload is split into
-N parts of size ieee->fts. The first fragment contains the SNAP header and the
-remaining packets are just data.
-
-If encryption is enabled, each fragment payload size is reduced by enough space
-to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
-So if you have 1500 bytes of payload with ieee->fts set to 500 without
-encryption it will take 3 frames. With WEP it will take 4 frames as the
-payload of each frame is reduced to 492 bytes.
-
-* SKB visualization
-*
-* ,- skb->data
-* |
-* | ETHERNET HEADER ,-<-- PAYLOAD
-* | | 14 bytes from skb->data
-* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
-* | | | |
-* |,-Dest.--. ,--Src.---. | | |
-* | 6 bytes| | 6 bytes | | | |
-* v | | | | | |
-* 0 | v 1 | v | v 2
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
-* ^ | ^ | ^ |
-* | | | | | |
-* | | | | `T' <---- 2 bytes for Type
-* | | | |
-* | | '---SNAP--' <-------- 6 bytes for SNAP
-* | |
-* `-IV--' <-------------------- 4 bytes for IV (WEP)
-*
-* SNAP HEADER
-*
-*/
-
-static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
-static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-
-static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
-{
- struct ieee80211_snap_hdr *snap;
- u8 *oui;
-
- snap = (struct ieee80211_snap_hdr *)data;
- snap->dsap = 0xaa;
- snap->ssap = 0xaa;
- snap->ctrl = 0x03;
-
- if (h_proto == 0x8137 || h_proto == 0x80f3)
- oui = P802_1H_OUI;
- else
- oui = RFC1042_OUI;
- snap->oui[0] = oui[0];
- snap->oui[1] = oui[1];
- snap->oui[2] = oui[2];
-
- *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
-
- return SNAP_SIZE + sizeof(u16);
-}
-
-int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
- struct sk_buff *frag, int hdr_len)
-{
- struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
- int res;
-
- /*
- * added to care about null crypt condition, to solve that system hangs
- * when shared keys error
- */
- if (!crypt || !crypt->ops)
- return -1;
-
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- struct ieee80211_hdr_4addr *header;
-
- if (ieee->tkip_countermeasures &&
- crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
- header = (struct ieee80211_hdr_4addr *)frag->data;
- if (net_ratelimit()) {
- netdev_dbg(ieee->dev, "TKIP countermeasures: dropped "
- "TX packet to %pM\n", header->addr1);
- }
- return -1;
- }
-#endif
- /*
- * To encrypt, frame format is:
- * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes)
- *
- * PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU
- * encryption.
- *
- * Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
- * call both MSDU and MPDU encryption functions from here.
- */
- atomic_inc(&crypt->refcnt);
- res = 0;
- if (crypt->ops->encrypt_msdu)
- res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
- if (res == 0 && crypt->ops->encrypt_mpdu)
- res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
-
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- netdev_info(ieee->dev, "Encryption failed: len=%d.\n", frag->len);
- ieee->ieee_stats.tx_discards++;
- return -1;
- }
-
- return 0;
-}
-
-
-void ieee80211_txb_free(struct ieee80211_txb *txb)
-{
- int i;
- if (unlikely(!txb))
- return;
- for (i = 0; i < txb->nr_frags; i++)
- if (txb->fragments[i])
- dev_kfree_skb_any(txb->fragments[i]);
- kfree(txb);
-}
-
-static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
- gfp_t gfp_mask)
-{
- struct ieee80211_txb *txb;
- int i;
- txb = kmalloc(
- sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags),
- gfp_mask);
- if (!txb)
- return NULL;
-
- memset(txb, 0, sizeof(struct ieee80211_txb));
- txb->nr_frags = nr_frags;
- txb->frag_size = txb_size;
-
- for (i = 0; i < nr_frags; i++) {
- txb->fragments[i] = dev_alloc_skb(txb_size);
- if (unlikely(!txb->fragments[i])) {
- i--;
- break;
- }
- }
- if (unlikely(i != nr_frags)) {
- while (i >= 0)
- dev_kfree_skb_any(txb->fragments[i--]);
- kfree(txb);
- return NULL;
- }
- return txb;
-}
-
-/*
- * Classify the to-be send data packet
- * Need to acquire the sent queue index.
- */
-static int ieee80211_classify(struct sk_buff *skb,
- struct ieee80211_network *network)
-{
- struct ether_header *eh = (struct ether_header *)skb->data;
- unsigned int wme_UP = 0;
-
- if (!network->QoS_Enable) {
- skb->priority = 0;
- return(wme_UP);
- }
-
- if (eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
- const struct iphdr *ih = (struct iphdr *)(skb->data +
- sizeof(struct ether_header));
- wme_UP = (ih->tos >> 5)&0x07;
- } else if (vlan_tx_tag_present(skb)) {/* vtag packet */
-#ifndef VLAN_PRI_SHIFT
-#define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */
-#define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */
-#endif
- u32 tag = vlan_tx_tag_get(skb);
- wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
- } else if (ETH_P_PAE == ntohs(((struct ethhdr *)skb->data)->h_proto)) {
- wme_UP = 7;
- }
-
- skb->priority = wme_UP;
- return(wme_UP);
-}
-
-/* SKBs are added to the ieee->tx_queue. */
-int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
- struct ieee80211_txb *txb = NULL;
- struct ieee80211_hdr_3addrqos *frag_hdr;
- int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
- unsigned long flags;
- struct net_device_stats *stats = &ieee->stats;
- int ether_type, encrypt;
- int bytes, fc, qos_ctl, hdr_len;
- struct sk_buff *skb_frag;
- struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
- .duration_id = 0,
- .seq_ctl = 0,
- .qos_ctl = 0
- };
- u8 dest[ETH_ALEN], src[ETH_ALEN];
-
- struct ieee80211_crypt_data* crypt;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- /*
- * If there is no driver handler to take the TXB, don't bother
- * creating it...
- */
- if ((!ieee->hard_start_xmit &&
- !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)) ||
- ((!ieee->softmac_data_hard_start_xmit &&
- (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
- netdev_warn(ieee->dev, "No xmit handler.\n");
- goto success;
- }
-
- ieee80211_classify(skb,&ieee->current_network);
- if (likely(ieee->raw_tx == 0)){
-
- if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
- netdev_warn(ieee->dev, "skb too small (%d).\n", skb->len);
- goto success;
- }
-
- ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
-
- crypt = ieee->crypt[ieee->tx_keyidx];
-
- encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
- ieee->host_encrypt && crypt && crypt->ops;
-
- if (!encrypt && ieee->ieee802_1x &&
- ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
- stats->tx_dropped++;
- goto success;
- }
-
- #ifdef CONFIG_IEEE80211_DEBUG
- if (crypt && !encrypt && ether_type == ETH_P_PAE) {
- struct eapol *eap = (struct eapol *)(skb->data +
- sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
- IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
- eap_get_type(eap->type));
- }
- #endif
-
- /* Save source and destination addresses */
- memcpy(&dest, skb->data, ETH_ALEN);
- memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
-
- /* Advance the SKB to the start of the payload */
- skb_pull(skb, sizeof(struct ethhdr));
-
- /* Determine total amount of storage required for TXB packets */
- bytes = skb->len + SNAP_SIZE + sizeof(u16);
-
- if (ieee->current_network.QoS_Enable) {
- if (encrypt)
- fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
- IEEE80211_FCTL_WEP;
- else
- fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
-
- } else {
- if (encrypt)
- fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
- IEEE80211_FCTL_WEP;
- else
- fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
- }
-
- if (ieee->iw_mode == IW_MODE_INFRA) {
- fc |= IEEE80211_FCTL_TODS;
- /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
- memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
- memcpy(&header.addr2, &src, ETH_ALEN);
- memcpy(&header.addr3, &dest, ETH_ALEN);
- } else if (ieee->iw_mode == IW_MODE_ADHOC) {
- /*
- * not From/To DS: Addr1 = DA, Addr2 = SA,
- * Addr3 = BSSID
- */
- memcpy(&header.addr1, dest, ETH_ALEN);
- memcpy(&header.addr2, src, ETH_ALEN);
- memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
- }
- header.frame_ctl = cpu_to_le16(fc);
-
- /*
- * Determine fragmentation size based on destination (multicast
- * and broadcast are not fragmented)
- */
- if (is_multicast_ether_addr(header.addr1)) {
- frag_size = MAX_FRAG_THRESHOLD;
- qos_ctl = QOS_CTL_NOTCONTAIN_ACK;
- } else {
- /* default:392 */
- frag_size = ieee->fts;
- qos_ctl = 0;
- }
-
- if (ieee->current_network.QoS_Enable) {
- hdr_len = IEEE80211_3ADDR_LEN + 2;
- /* skb->priority is set in the ieee80211_classify() */
- qos_ctl |= skb->priority;
- header.qos_ctl = cpu_to_le16(qos_ctl);
- } else {
- hdr_len = IEEE80211_3ADDR_LEN;
- }
-
- /*
- * Determine amount of payload per fragment. Regardless of if
- * this stack is providing the full 802.11 header, one will
- * eventually be affixed to this fragment -- so we must account
- * for it when determining the amount of payload space.
- */
- bytes_per_frag = frag_size - hdr_len;
- if (ieee->config &
- (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- bytes_per_frag -= IEEE80211_FCS_LEN;
-
- /* Each fragment may need to have room for encryption pre/postfix */
- if (encrypt)
- bytes_per_frag -= crypt->ops->extra_prefix_len +
- crypt->ops->extra_postfix_len;
-
- /*
- * Number of fragments is the total bytes_per_frag /
- * payload_per_fragment
- */
- nr_frags = bytes / bytes_per_frag;
- bytes_last_frag = bytes % bytes_per_frag;
- if (bytes_last_frag)
- nr_frags++;
- else
- bytes_last_frag = bytes_per_frag;
-
- /*
- * When we allocate the TXB we allocate enough space for the
- * reserve and full fragment bytes (bytes_per_frag doesn't
- * include prefix, postfix, header, FCS, etc.)
- */
- txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
- if (unlikely(!txb)) {
- netdev_warn(ieee->dev, "Could not allocate TXB\n");
- goto failed;
- }
- txb->encrypted = encrypt;
- txb->payload_size = bytes;
-
- for (i = 0; i < nr_frags; i++) {
- skb_frag = txb->fragments[i];
- skb_frag->priority = UP2AC(skb->priority);
- if (encrypt)
- skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
-
- frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(
- skb_frag, hdr_len);
- memcpy(frag_hdr, &header, hdr_len);
-
- /*
- * If this is not the last fragment, then add the MOREFRAGS
- * bit to the frame control
- */
- if (i != nr_frags - 1) {
- frag_hdr->frame_ctl = cpu_to_le16(
- fc | IEEE80211_FCTL_MOREFRAGS);
- bytes = bytes_per_frag;
-
- } else {
- /* The last fragment takes the remaining length */
- bytes = bytes_last_frag;
- }
- if (ieee->current_network.QoS_Enable) {
- /*
- * add 1 only indicate to corresponding seq
- * number control 2006/7/12
- */
- frag_hdr->seq_ctl = cpu_to_le16(
- ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
- } else {
- frag_hdr->seq_ctl = cpu_to_le16(
- ieee->seq_ctrl[0]<<4 | i);
- }
-
- /* Put a SNAP header on the first fragment */
- if (i == 0) {
- ieee80211_put_snap(
- skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
- ether_type);
- bytes -= SNAP_SIZE + sizeof(u16);
- }
-
- memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
-
- /* Advance the SKB... */
- skb_pull(skb, bytes);
-
- /*
- * Encryption routine will move the header forward in
- * order to insert the IV between the header and the
- * payload
- */
- if (encrypt)
- ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
- if (ieee->config &
- (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- skb_put(skb_frag, 4);
- }
- /* Advance sequence number in data frame. */
- if (ieee->current_network.QoS_Enable) {
- if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
- ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
- else
- ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
- } else {
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
- }
- } else {
- if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
- netdev_warn(ieee->dev, "skb too small (%d).\n", skb->len);
- goto success;
- }
-
- txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
- if (!txb) {
- netdev_warn(ieee->dev, "Could not allocate TXB\n");
- goto failed;
- }
-
- txb->encrypted = 0;
- txb->payload_size = skb->len;
- memcpy(skb_put(txb->fragments[0], skb->len), skb->data, skb->len);
- }
-
- success:
- spin_unlock_irqrestore(&ieee->lock, flags);
- dev_kfree_skb_any(skb);
- if (txb) {
- if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) {
- ieee80211_softmac_xmit(txb, ieee);
- } else {
- if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
- stats->tx_packets++;
- stats->tx_bytes += txb->payload_size;
- return NETDEV_TX_OK;
- }
- ieee80211_txb_free(txb);
- }
- }
-
- return NETDEV_TX_OK;
-
- failed:
- spin_unlock_irqrestore(&ieee->lock, flags);
- netif_stop_queue(dev);
- stats->tx_errors++;
- return NETDEV_TX_BUSY;
-
-}
+++ /dev/null
-/*
- * Copyright(c) 2004 Intel Corporation. All rights reserved.
- *
- * Portions of this file are based on the WEP enablement code provided by the
- * Host AP project hostap-drivers v0.1.3
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * 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.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * 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
- */
-
-#include <linux/wireless.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/etherdevice.h>
-
-#include "ieee80211.h"
-static const char *ieee80211_modes[] = {
- "?", "a", "b", "ab", "g", "ag", "bg", "abg"
-};
-
-#define MAX_CUSTOM_LEN 64
-static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
- char *start, char *stop,
- struct ieee80211_network *network,
- struct iw_request_info *info)
-{
- char custom[MAX_CUSTOM_LEN];
- char *p;
- struct iw_event iwe;
- int i, j;
- u8 max_rate, rate;
-
- /* First entry *MUST* be the AP MAC address */
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- ether_addr_copy(iwe.u.ap_addr.sa_data, network->bssid);
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
-
- /* Remaining entries will be displayed in the order we provide them */
-
- /* Add the ESSID */
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.flags = 1;
- if (network->ssid_len == 0) {
- iwe.u.data.length = sizeof("<hidden>");
- start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
- } else {
- iwe.u.data.length = min_t(u8, network->ssid_len, 32);
- start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
- }
- /* Add the protocol name */
- iwe.cmd = SIOCGIWNAME;
- snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
-
- /* Add mode */
- iwe.cmd = SIOCGIWMODE;
- if (network->capability &
- (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
- if (network->capability & WLAN_CAPABILITY_BSS)
- iwe.u.mode = IW_MODE_MASTER;
- else
- iwe.u.mode = IW_MODE_ADHOC;
-
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
- }
-
- /* Add frequency/channel */
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = network->channel;
- iwe.u.freq.e = 0;
- iwe.u.freq.i = 0;
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
-
- /* Add encryption capability */
- iwe.cmd = SIOCGIWENCODE;
- if (network->capability & WLAN_CAPABILITY_PRIVACY)
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- else
- iwe.u.data.flags = IW_ENCODE_DISABLED;
- iwe.u.data.length = 0;
- start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
-
- /* Add basic and extended rates */
- max_rate = 0;
- p = custom;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
- for (i = 0, j = 0; i < network->rates_len; ) {
- if (j < network->rates_ex_len &&
- ((network->rates_ex[j] & 0x7F) <
- (network->rates[i] & 0x7F)))
- rate = network->rates_ex[j++] & 0x7F;
- else
- rate = network->rates[i++] & 0x7F;
- if (rate > max_rate)
- max_rate = rate;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
- }
- for (; j < network->rates_ex_len; j++) {
- rate = network->rates_ex[j] & 0x7F;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
- if (rate > max_rate)
- max_rate = rate;
- }
-
- iwe.cmd = SIOCGIWRATE;
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
- iwe.u.bitrate.value = max_rate * 500000;
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
-
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
- /* Add quality statistics */
- /* TODO: Fix these values... */
- if (network->stats.signal == 0 || network->stats.rssi == 0)
- netdev_info(ieee->dev, "========>signal:%d, rssi:%d\n",
- network->stats.signal, network->stats.rssi);
- iwe.cmd = IWEVQUAL;
- iwe.u.qual.qual = network->stats.signalstrength;
- iwe.u.qual.level = network->stats.signal;
- iwe.u.qual.noise = network->stats.noise;
- iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
- if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
- iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
- if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
- iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
- if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
- iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
- iwe.u.qual.updated = 7;
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
-
- iwe.cmd = IWEVCUSTOM;
- p = custom;
-
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
- memset(&iwe, 0, sizeof(iwe));
- if (network->wpa_ie_len) {
- char buf[MAX_WPA_IE_LEN];
- memcpy(buf, network->wpa_ie, network->wpa_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = network->wpa_ie_len;
- start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- }
-
- memset(&iwe, 0, sizeof(iwe));
- if (network->rsn_ie_len) {
- char buf[MAX_WPA_IE_LEN];
- memcpy(buf, network->rsn_ie, network->rsn_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = network->rsn_ie_len;
- start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- }
-
- /* Add EXTRA: Age to display seconds since last beacon/probe response
- * for given network.
- */
- iwe.cmd = IWEVCUSTOM;
- p = custom;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
- return start;
-}
-
-int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ieee80211_network *network;
- unsigned long flags;
- int err = 0;
- char *ev = extra;
- char *stop = ev + wrqu->data.length;
- int i = 0;
-
- IEEE80211_DEBUG_WX("Getting scan\n");
- down(&ieee->wx_sem);
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (!ieee->bHwRadioOff) {
- list_for_each_entry(network, &ieee->network_list, list) {
- i++;
-
- if ((stop-ev) < 200) {
- err = -E2BIG;
- break;
- }
- if (ieee->scan_age == 0 ||
- time_after(network->last_scanned + ieee->scan_age, jiffies)) {
- ev = rtl818x_translate_scan(ieee, ev, stop, network, info);
- } else
- IEEE80211_DEBUG_SCAN(
- "Not showing network '%s ("
- "%pM)' due to age (%lums).\n",
- escape_essid(network->ssid,
- network->ssid_len),
- network->bssid,
- (jiffies - network->last_scanned) / (HZ / 100));
- }
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
- up(&ieee->wx_sem);
- wrqu->data.length = ev - extra;
- wrqu->data.flags = 0;
- IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
-
- return err;
-}
-
-int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *keybuf)
-{
- struct iw_point *erq = &(wrqu->encoding);
- struct net_device *dev = ieee->dev;
- struct ieee80211_security sec = {
- .flags = 0
- };
- int i, key, key_provided, len;
- struct ieee80211_crypt_data **crypt;
-
- IEEE80211_DEBUG_WX("SET_ENCODE\n");
-
- key = erq->flags & IW_ENCODE_INDEX;
- if (key) {
- if (key > WEP_KEYS)
- return -EINVAL;
- key--;
- key_provided = 1;
- } else {
- key_provided = 0;
- key = ieee->tx_keyidx;
- }
-
- IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
- "provided" : "default");
-
- crypt = &ieee->crypt[key];
-
- if (erq->flags & IW_ENCODE_DISABLED) {
- if (key_provided && *crypt) {
- IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
- key);
- ieee80211_crypt_delayed_deinit(ieee, crypt);
- } else
- IEEE80211_DEBUG_WX("Disabling encryption.\n");
-
- /* Check all the keys to see if any are still configured,
- * and if no key index was provided, de-init them all.
- */
- for (i = 0; i < WEP_KEYS; i++) {
- if (ieee->crypt[i] != NULL) {
- if (key_provided)
- break;
- ieee80211_crypt_delayed_deinit(
- ieee, &ieee->crypt[i]);
- }
- }
-
- if (i == WEP_KEYS) {
- sec.enabled = 0;
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_ENABLED | SEC_LEVEL;
- }
-
- goto done;
- }
-
- sec.enabled = 1;
- sec.flags |= SEC_ENABLED;
-
- if (*crypt != NULL && (*crypt)->ops != NULL &&
- strcmp((*crypt)->ops->name, "WEP") != 0) {
- /* changing to use WEP; deinit previously used algorithm
- * on this key.
- */
- ieee80211_crypt_delayed_deinit(ieee, crypt);
- }
-
- if (*crypt == NULL) {
- struct ieee80211_crypt_data *new_crypt;
-
- /* take WEP into use */
- new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
- GFP_KERNEL);
- if (new_crypt == NULL)
- return -ENOMEM;
- new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- if (!new_crypt->ops)
- new_crypt->ops = ieee80211_get_crypto_ops("WEP");
-
- if (new_crypt->ops)
- new_crypt->priv = new_crypt->ops->init(key);
-
- if (!new_crypt->ops || !new_crypt->priv) {
- kfree(new_crypt);
- new_crypt = NULL;
-
- netdev_warn(ieee->dev,
- "could not initialize WEP: load module ieee80211_crypt_wep\n");
- return -EOPNOTSUPP;
- }
- *crypt = new_crypt;
- }
-
- /* If a new key was provided, set it up */
- if (erq->length > 0) {
- len = erq->length <= 5 ? 5 : 13;
- memcpy(sec.keys[key], keybuf, erq->length);
- if (len > erq->length)
- memset(sec.keys[key] + erq->length, 0,
- len - erq->length);
- IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
- key, escape_essid(sec.keys[key], len),
- erq->length, len);
- sec.key_sizes[key] = len;
- (*crypt)->ops->set_key(sec.keys[key], len, NULL,
- (*crypt)->priv);
- sec.flags |= (1 << key);
- /* This ensures a key will be activated if no key is
- * explicitly set.
- */
- if (key == sec.active_key)
- sec.flags |= SEC_ACTIVE_KEY;
- ieee->tx_keyidx = key;
- } else {
- len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
- NULL, (*crypt)->priv);
- if (len == 0) {
- /* Set a default key of all 0 */
- IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
- key);
- memset(sec.keys[key], 0, 13);
- (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
- (*crypt)->priv);
- sec.key_sizes[key] = 13;
- sec.flags |= (1 << key);
- }
-
- /* No key data - just set the default TX key index */
- if (key_provided) {
- IEEE80211_DEBUG_WX(
- "Setting key %d to default Tx key.\n", key);
- ieee->tx_keyidx = key;
- sec.active_key = key;
- sec.flags |= SEC_ACTIVE_KEY;
- }
- }
-
- done:
- ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
- sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
- sec.flags |= SEC_AUTH_MODE;
- IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
- "OPEN" : "SHARED KEY");
-
- /* For now we just support WEP, so only set that security level...
- * TODO: When WPA is added this is one place that needs to change
- */
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
-
- if (ieee->set_security)
- ieee->set_security(dev, &sec);
-
- /* Do not reset port if card is in Managed mode since resetting will
- * generate new IEEE 802.11 authentication which may end up in looping
- * with IEEE 802.1X. If your hardware requires a reset after WEP
- * configuration (for example... Prism2), implement the reset_port in
- * the callbacks structures used to initialize the 802.11 stack.
- */
- if (ieee->reset_on_keychange &&
- ieee->iw_mode != IW_MODE_INFRA &&
- ieee->reset_port && ieee->reset_port(dev)) {
- netdev_dbg(ieee->dev, "reset_port failed\n");
- return -EINVAL;
- }
- return 0;
-}
-
-int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *keybuf)
-{
- struct iw_point *erq = &(wrqu->encoding);
- int len, key;
- struct ieee80211_crypt_data *crypt;
-
- IEEE80211_DEBUG_WX("GET_ENCODE\n");
-
- if (ieee->iw_mode == IW_MODE_MONITOR)
- return -1;
-
- key = erq->flags & IW_ENCODE_INDEX;
- if (key) {
- if (key > WEP_KEYS)
- return -EINVAL;
- key--;
- } else
- key = ieee->tx_keyidx;
-
- crypt = ieee->crypt[key];
- erq->flags = key + 1;
-
- if (crypt == NULL || crypt->ops == NULL) {
- erq->length = 0;
- erq->flags |= IW_ENCODE_DISABLED;
- return 0;
- }
-
- if (strcmp(crypt->ops->name, "WEP") != 0) {
- /* only WEP is supported with wireless extensions, so just
- * report that encryption is used.
- */
- erq->length = 0;
- erq->flags |= IW_ENCODE_ENABLED;
- return 0;
- }
-
- len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
- erq->length = (len >= 0 ? len : 0);
-
- erq->flags |= IW_ENCODE_ENABLED;
-
- if (ieee->open_wep)
- erq->flags |= IW_ENCODE_OPEN;
- else
- erq->flags |= IW_ENCODE_RESTRICTED;
-
- return 0;
-}
-
-int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct net_device *dev = ieee->dev;
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int i, idx, ret = 0;
- int group_key = 0;
- const char *alg;
- struct ieee80211_crypto_ops *ops;
- struct ieee80211_crypt_data **crypt;
-
- struct ieee80211_security sec = {
- .flags = 0,
- };
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx) {
- if (idx < 1 || idx > WEP_KEYS)
- return -EINVAL;
- idx--;
- } else
- idx = ieee->tx_keyidx;
-
- if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
- crypt = &ieee->crypt[idx];
- group_key = 1;
- } else {
- /* some Cisco APs use idx>0 for unicast in dynamic WEP */
- if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
- return -EINVAL;
- if (ieee->iw_mode == IW_MODE_INFRA)
- crypt = &ieee->crypt[idx];
- else
- return -EINVAL;
- }
-
- sec.flags |= SEC_ENABLED;
- if ((encoding->flags & IW_ENCODE_DISABLED) ||
- ext->alg == IW_ENCODE_ALG_NONE) {
- if (*crypt)
- ieee80211_crypt_delayed_deinit(ieee, crypt);
-
- for (i = 0; i < WEP_KEYS; i++)
- if (ieee->crypt[i] != NULL)
- break;
-
- if (i == WEP_KEYS) {
- sec.enabled = 0;
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_LEVEL;
- }
- goto done;
- }
-
- sec.enabled = 1;
-
- switch (ext->alg) {
- case IW_ENCODE_ALG_WEP:
- alg = "WEP";
- break;
- case IW_ENCODE_ALG_TKIP:
- alg = "TKIP";
- break;
- case IW_ENCODE_ALG_CCMP:
- alg = "CCMP";
- break;
- default:
- IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
- dev->name, ext->alg);
- ret = -EINVAL;
- goto done;
- }
-
- ops = ieee80211_get_crypto_ops(alg);
- if (ops == NULL)
- ops = ieee80211_get_crypto_ops(alg);
- if (ops == NULL) {
- IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
- dev->name, ext->alg);
- netdev_err(ieee->dev, "========>unknown crypto alg %d\n",
- ext->alg);
- ret = -EINVAL;
- goto done;
- }
-
- if (*crypt == NULL || (*crypt)->ops != ops) {
- struct ieee80211_crypt_data *new_crypt;
-
- ieee80211_crypt_delayed_deinit(ieee, crypt);
-
- new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
- if (new_crypt == NULL) {
- ret = -ENOMEM;
- goto done;
- }
- new_crypt->ops = ops;
- if (new_crypt->ops)
- new_crypt->priv = new_crypt->ops->init(idx);
- if (new_crypt->priv == NULL) {
- kfree(new_crypt);
- ret = -EINVAL;
- goto done;
- }
- *crypt = new_crypt;
-
- }
-
- if (ext->key_len > 0 && (*crypt)->ops->set_key &&
- (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
- (*crypt)->priv) < 0) {
- IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
- netdev_err(ieee->dev, "key setting failed\n");
- ret = -EINVAL;
- goto done;
- }
-#if 1
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- ieee->tx_keyidx = idx;
- sec.active_key = idx;
- sec.flags |= SEC_ACTIVE_KEY;
- }
-
- if (ext->alg != IW_ENCODE_ALG_NONE) {
- memcpy(sec.keys[idx], ext->key, ext->key_len);
- sec.key_sizes[idx] = ext->key_len;
- sec.flags |= (1 << idx);
- if (ext->alg == IW_ENCODE_ALG_WEP) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1;
- } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_2;
- } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_3;
- }
- /* Don't set sec level for group keys. */
- if (group_key)
- sec.flags &= ~SEC_LEVEL;
- }
-#endif
-done:
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
-
- if (ieee->reset_on_keychange &&
- ieee->iw_mode != IW_MODE_INFRA &&
- ieee->reset_port && ieee->reset_port(dev)) {
- IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
- return -EINVAL;
- }
-
- return ret;
-}
-
-int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_mlme *mlme = (struct iw_mlme *) extra;
-#if 1
- switch (mlme->cmd) {
- case IW_MLME_DEAUTH:
- case IW_MLME_DISASSOC:
- ieee80211_disassociate(ieee);
- break;
- default:
- return -EOPNOTSUPP;
- }
-#endif
- return 0;
-}
-
-int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- struct iw_param *data, char *extra)
-{
- switch (data->flags & IW_AUTH_INDEX) {
- case IW_AUTH_WPA_VERSION:
- /* need to support wpa2 here */
- break;
- case IW_AUTH_CIPHER_PAIRWISE:
- case IW_AUTH_CIPHER_GROUP:
- case IW_AUTH_KEY_MGMT:
- /* Host AP driver does not use these parameters and allows
- * wpa_supplicant to control them internally.
- */
- break;
- case IW_AUTH_TKIP_COUNTERMEASURES:
- ieee->tkip_countermeasures = data->value;
- break;
- case IW_AUTH_DROP_UNENCRYPTED:
- ieee->drop_unencrypted = data->value;
- break;
-
- case IW_AUTH_80211_AUTH_ALG:
- ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM) ? 1 : 0;
- break;
-
-#if 1
- case IW_AUTH_WPA_ENABLED:
- ieee->wpa_enabled = (data->value) ? 1 : 0;
- break;
-
-#endif
- case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- ieee->ieee802_1x = data->value;
- break;
- case IW_AUTH_PRIVACY_INVOKED:
- ieee->privacy_invoked = data->value;
- break;
- default:
- return -EOPNOTSUPP;
- }
- return 0;
-}
-
-#if 1
-int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
-{
- u8 *buf = NULL;
-
- if (len > MAX_WPA_IE_LEN || (len && ie == NULL)) {
- netdev_err(ieee->dev, "return error out, len:%zu\n", len);
- return -EINVAL;
- }
-
- if (len) {
- if (len != ie[1]+2) {
- netdev_err(ieee->dev, "len:%zu, ie:%d\n", len, ie[1]);
- return -EINVAL;
- }
- buf = kmemdup(ie, len, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = buf;
- ieee->wpa_ie_len = len;
- } else {
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = NULL;
- ieee->wpa_ie_len = 0;
- }
-
- return 0;
-
-}
-#endif
+++ /dev/null
-/*
- * This is part of rtl8180 OpenSource driver.
- * Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
- * Released under the terms of GPL (General Public Licence)
- *
- * Parts of this driver are based on the GPL part of the official realtek driver
- *
- * Parts of this driver are based on the rtl8180 driver skeleton from Patric
- * Schenke & Andres Salomon
- *
- * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
- *
- * We want to thanks the Authors of those projects and the Ndiswrapper project
- * Authors.
- */
-
-#ifndef R8180H
-#define R8180H
-
-#include <linux/interrupt.h>
-
-#define RTL8180_MODULE_NAME "r8180"
-#define DMESG(x, a...) printk(KERN_INFO RTL8180_MODULE_NAME ": " x "\n", ## a)
-#define DMESGW(x, a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": WW:" x "\n", ## a)
-#define DMESGE(x, a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": EE:" x "\n", ## a)
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/etherdevice.h>
-#include <linux/delay.h>
-#include <linux/rtnetlink.h> /* for rtnl_lock() */
-#include <linux/wireless.h>
-#include <linux/timer.h>
-#include <linux/proc_fs.h> /* Necessary because we use the proc fs. */
-#include <linux/if_arp.h>
-#include "ieee80211/ieee80211.h"
-#include <asm/io.h>
-
-#define EPROM_93c46 0
-#define EPROM_93c56 1
-
-#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
-
-#define DEFAULT_FRAG_THRESHOLD 2342U
-#define MIN_FRAG_THRESHOLD 256U
-#define DEFAULT_RTS_THRESHOLD 2342U
-#define MIN_RTS_THRESHOLD 0U
-#define MAX_RTS_THRESHOLD 2342U
-#define DEFAULT_BEACONINTERVAL 0x64U
-
-#define DEFAULT_RETRY_RTS 7
-#define DEFAULT_RETRY_DATA 7
-
-#define BEACON_QUEUE 6
-
-#define aSifsTime 10
-
-#define sCrcLng 4
-#define sAckCtsLng 112 /* bits in ACK and CTS frames. */
-/* +by amy 080312. */
-#define RATE_ADAPTIVE_TIMER_PERIOD 300
-
-enum wireless_mode {
- WIRELESS_MODE_UNKNOWN = 0x00,
- WIRELESS_MODE_A = 0x01,
- WIRELESS_MODE_B = 0x02,
- WIRELESS_MODE_G = 0x04,
- WIRELESS_MODE_AUTO = 0x08,
-};
-
-struct chnl_access_setting {
- u16 sifs_timer;
- u16 difs_timer;
- u16 slot_time_timer;
- u16 eifs_timer;
- u16 cwmin_index;
- u16 cwmax_index;
-};
-
-enum nic_t {
- NIC_8185 = 1,
- NIC_8185B
-};
-
-typedef u32 AC_CODING;
-#define AC0_BE 0 /* ACI: 0x00 */ /* Best Effort. */
-#define AC1_BK 1 /* ACI: 0x01 */ /* Background. */
-#define AC2_VI 2 /* ACI: 0x10 */ /* Video. */
-#define AC3_VO 3 /* ACI: 0x11 */ /* Voice. */
-#define AC_MAX 4 /* Max: define total number; Should not to be used as a real
- * enum.
- */
-
-/*
- * ECWmin/ECWmax field.
- * Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
- */
-typedef union _ECW {
- u8 charData;
- struct {
- u8 ECWmin:4;
- u8 ECWmax:4;
- } f; /* Field */
-} ECW, *PECW;
-
-/*
- * ACI/AIFSN Field. Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
- */
-typedef union _ACI_AIFSN {
- u8 charData;
-
- struct {
- u8 AIFSN:4;
- u8 ACM:1;
- u8 ACI:2;
- u8 Reserved:1;
- } f; /* Field */
-} ACI_AIFSN, *PACI_AIFSN;
-
-/*
- * AC Parameters Record Format.
- * Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
- */
-typedef union _AC_PARAM {
- u32 longData;
- u8 charData[4];
-
- struct {
- ACI_AIFSN AciAifsn;
- ECW Ecw;
- u16 TXOPLimit;
- } f; /* Field */
-} AC_PARAM, *PAC_PARAM;
-
-struct buffer {
- struct buffer *next;
- u32 *buf;
- dma_addr_t dma;
-};
-
-/* YJ,modified,080828. */
-struct stats {
- unsigned long txrdu;
- unsigned long rxrdu;
- unsigned long rxnolast;
- unsigned long rxnodata;
- unsigned long rxnopointer;
- unsigned long txnperr;
- unsigned long txresumed;
- unsigned long rxerr;
- unsigned long rxoverflow;
- unsigned long rxint;
- unsigned long txbkpokint;
- unsigned long txbepoking;
- unsigned long txbkperr;
- unsigned long txbeperr;
- unsigned long txnpokint;
- unsigned long txhpokint;
- unsigned long txhperr;
- unsigned long ints;
- unsigned long shints;
- unsigned long txoverflow;
- unsigned long rxdmafail;
- unsigned long txbeacon;
- unsigned long txbeaconerr;
- unsigned long txlpokint;
- unsigned long txlperr;
- unsigned long txretry; /* retry number tony 20060601 */
- unsigned long rxcrcerrmin; /* crc error (0-500) */
- unsigned long rxcrcerrmid; /* crc error (500-1000) */
- unsigned long rxcrcerrmax; /* crc error (>1000) */
- unsigned long rxicverr; /* ICV error */
-};
-
-#define MAX_LD_SLOT_NUM 10
-#define KEEP_ALIVE_INTERVAL 20 /* in seconds. */
-#define CHECK_FOR_HANG_PERIOD 2 /* be equal to watchdog check time. */
-#define DEFAULT_KEEP_ALIVE_LEVEL 1
-#define DEFAULT_SLOT_NUM 2
-#define POWER_PROFILE_AC 0
-#define POWER_PROFILE_BATTERY 1
-
-struct link_detect_t {
- u32 rx_frame_num[MAX_LD_SLOT_NUM]; /* number of Rx Frame.
- * CheckForHang_period to determine
- * link status.
- */
- u16 slot_num; /* number of CheckForHang period to determine link status,
- * default is 2.
- */
- u16 slot_index;
- u32 num_tx_ok_in_period; /* number of packet transmitted during
- * CheckForHang.
- */
- u32 num_rx_ok_in_period; /* number of packet received during
- * CheckForHang.
- */
- u8 idle_count; /* (KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD) */
- u32 last_num_tx_unicast;
- u32 last_num_rx_unicast;
-
- bool b_busy_traffic; /* when it is set to 1, UI cann't scan at will. */
-};
-
-/* YJ,modified,080828,end */
-
-/* by amy for led
- * ==========================================================================
- * LED customization.
- * ==========================================================================
- */
-enum led_strategy_8185 {
- SW_LED_MODE0,
- SW_LED_MODE1,
- HW_LED, /* HW control 2 LEDs, LED0 and LED1 (there are 4 different
- * control modes). */
-};
-
-enum rt_rf_power_state {
- RF_ON,
- RF_SLEEP,
- RF_OFF
-};
-
-enum _ReasonCode {
- unspec_reason = 0x1,
- auth_not_valid = 0x2,
- deauth_lv_ss = 0x3,
- inactivity = 0x4,
- ap_overload = 0x5,
- class2_err = 0x6,
- class3_err = 0x7,
- disas_lv_ss = 0x8,
- asoc_not_auth = 0x9,
-
- /* ----MIC_CHECK */
- mic_failure = 0xe,
- /* ----END MIC_CHECK */
-
- /* Reason code defined in 802.11i D10.0 p.28. */
- invalid_IE = 0x0d,
- four_way_tmout = 0x0f,
- two_way_tmout = 0x10,
- IE_dismatch = 0x11,
- invalid_Gcipher = 0x12,
- invalid_Pcipher = 0x13,
- invalid_AKMP = 0x14,
- unsup_RSNIEver = 0x15,
- invalid_RSNIE = 0x16,
- auth_802_1x_fail = 0x17,
- ciper_reject = 0x18,
-
- /* Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie,
- * 2005-11-15.
- */
- QoS_unspec = 0x20, /* 32 */
- QAP_bandwidth = 0x21, /* 33 */
- poor_condition = 0x22, /* 34 */
- no_facility = 0x23, /* 35 */
- /* Where is 36??? */
- req_declined = 0x25, /* 37 */
- invalid_param = 0x26, /* 38 */
- req_not_honored = 0x27, /* 39 */
- TS_not_created = 0x2F, /* 47 */
- DL_not_allowed = 0x30, /* 48 */
- dest_not_exist = 0x31, /* 49 */
- dest_not_QSTA = 0x32, /* 50 */
-};
-
-enum rt_ps_mode {
- ACTIVE, /* Active/Continuous access. */
- MAX_PS, /* Max power save mode. */
- FAST_PS /* Fast power save mode. */
-};
-
-/* by amy for power save. */
-struct r8180_priv {
- struct pci_dev *pdev;
-
- short epromtype;
- int irq;
- struct ieee80211_device *ieee80211;
-
- short plcp_preamble_mode; /* 0:auto 1:short 2:long */
-
- spinlock_t irq_th_lock;
- spinlock_t tx_lock;
- spinlock_t ps_lock;
- spinlock_t rf_ps_lock;
-
- u16 irq_mask;
- short irq_enabled;
- struct net_device *dev;
- short chan;
- short sens;
- short max_sens;
- u8 chtxpwr[15]; /* channels from 1 to 14, 0 not used. */
- u8 chtxpwr_ofdm[15]; /* channels from 1 to 14, 0 not used. */
- u8 channel_plan; /* it's the channel plan index. */
- short up;
- short crcmon; /* if 1 allow bad crc frame reception in monitor mode. */
-
- struct timer_list scan_timer;
- spinlock_t scan_lock;
- u8 active_probe;
- struct semaphore wx_sem;
- short hw_wep;
-
- short digphy;
- short antb;
- short diversity;
- u32 key0[4];
- short (*rf_set_sens)(struct net_device *dev, short sens);
- void (*rf_set_chan)(struct net_device *dev, short ch);
- void (*rf_close)(struct net_device *dev);
- void (*rf_init)(struct net_device *dev);
- void (*rf_sleep)(struct net_device *dev);
- void (*rf_wakeup)(struct net_device *dev);
- /* short rate; */
- short promisc;
- /* stats */
- struct stats stats;
- struct link_detect_t link_detect; /* YJ,add,080828 */
- struct iw_statistics wstats;
-
- /* RX stuff. */
- u32 *rxring;
- u32 *rxringtail;
- dma_addr_t rxringdma;
- struct buffer *rxbuffer;
- struct buffer *rxbufferhead;
- int rxringcount;
- u16 rxbuffersize;
-
- struct sk_buff *rx_skb;
-
- short rx_skb_complete;
-
- u32 rx_prevlen;
-
- u32 *txmapring;
- u32 *txbkpring;
- u32 *txbepring;
- u32 *txvipring;
- u32 *txvopring;
- u32 *txhpring;
- dma_addr_t txmapringdma;
- dma_addr_t txbkpringdma;
- dma_addr_t txbepringdma;
- dma_addr_t txvipringdma;
- dma_addr_t txvopringdma;
- dma_addr_t txhpringdma;
- u32 *txmapringtail;
- u32 *txbkpringtail;
- u32 *txbepringtail;
- u32 *txvipringtail;
- u32 *txvopringtail;
- u32 *txhpringtail;
- u32 *txmapringhead;
- u32 *txbkpringhead;
- u32 *txbepringhead;
- u32 *txvipringhead;
- u32 *txvopringhead;
- u32 *txhpringhead;
- struct buffer *txmapbufs;
- struct buffer *txbkpbufs;
- struct buffer *txbepbufs;
- struct buffer *txvipbufs;
- struct buffer *txvopbufs;
- struct buffer *txhpbufs;
- struct buffer *txmapbufstail;
- struct buffer *txbkpbufstail;
- struct buffer *txbepbufstail;
- struct buffer *txvipbufstail;
- struct buffer *txvopbufstail;
- struct buffer *txhpbufstail;
-
- int txringcount;
- int txbuffsize;
- struct tasklet_struct irq_rx_tasklet;
- u8 dma_poll_mask;
-
- /* adhoc/master mode stuff. */
- u32 *txbeaconringtail;
- dma_addr_t txbeaconringdma;
- u32 *txbeaconring;
- int txbeaconcount;
- struct buffer *txbeaconbufs;
- struct buffer *txbeaconbufstail;
-
- u8 retry_data;
- u8 retry_rts;
- u16 rts;
-
- /* by amy for led. */
- enum led_strategy_8185 led_strategy;
- /* by amy for led. */
-
- /* by amy for power save. */
- struct timer_list watch_dog_timer;
- bool bInactivePs;
- bool bSwRfProcessing;
- enum rt_rf_power_state eInactivePowerState;
- enum rt_rf_power_state eRFPowerState;
- u32 RfOffReason;
- bool RFChangeInProgress;
- bool SetRFPowerStateInProgress;
- u8 RFProgType;
- bool bLeisurePs;
- enum rt_ps_mode dot11PowerSaveMode;
- u8 TxPollingTimes;
-
- bool bApBufOurFrame; /* TRUE if AP buffer our unicast data , we will
- * keep eAwake until receive data or timeout.
- */
- u8 WaitBufDataBcnCount;
- u8 WaitBufDataTimeOut;
-
- /* by amy for power save. */
- /* by amy for antenna. */
- u8 EEPROMSwAntennaDiversity;
- bool EEPROMDefaultAntenna1;
- u8 RegSwAntennaDiversityMechanism;
- bool bSwAntennaDiverity;
- u8 RegDefaultAntenna;
- bool bDefaultAntenna1;
- u8 SignalStrength;
- long Stats_SignalStrength;
- long LastSignalStrengthInPercent; /* In percentage, used for smoothing,
- * e.g. Moving Average.
- */
- u8 SignalQuality; /* in 0-100 index. */
- long Stats_SignalQuality;
- long RecvSignalPower; /* in dBm. */
- long Stats_RecvSignalPower;
- u8 LastRxPktAntenna; /* +by amy 080312 Antenna which received the lasted
- * packet. 0: Aux, 1:Main. Added by Roger,
- * 2008.01.25.
- */
- u32 AdRxOkCnt;
- long AdRxSignalStrength;
- u8 CurrAntennaIndex; /* Index to current Antenna (both Tx and Rx). */
- u8 AdTickCount; /* Times of SwAntennaDiversityTimer happened. */
- u8 AdCheckPeriod; /* # of period SwAntennaDiversityTimer to check Rx
- * signal strength for SW Antenna Diversity.
- */
- u8 AdMinCheckPeriod; /* Min value of AdCheckPeriod. */
- u8 AdMaxCheckPeriod; /* Max value of AdCheckPeriod. */
- long AdRxSsThreshold; /* Signal strength threshold to switch antenna. */
- long AdMaxRxSsThreshold; /* Max value of AdRxSsThreshold. */
- bool bAdSwitchedChecking; /* TRUE if we shall shall check Rx signal
- * strength for last time switching antenna.
- */
- long AdRxSsBeforeSwitched; /* Rx signal strength before we switched
- * antenna.
- */
- struct timer_list SwAntennaDiversityTimer;
- /* by amy for antenna {by amy 080312 */
-
- /* Crystal calibration. Added by Roger, 2007.12.11. */
-
- bool bXtalCalibration; /* Crystal calibration.*/
- u8 XtalCal_Xin; /* Crystal calibration for Xin. 0~7.5pF */
- u8 XtalCal_Xout; /* Crystal calibration for Xout. 0~7.5pF */
-
- /* Tx power tracking with thermal meter indication.
- * Added by Roger, 2007.12.11.
- */
-
- bool bTxPowerTrack; /* Tx Power tracking. */
- u8 ThermalMeter; /* Thermal meter reference indication. */
-
- /* Dynamic Initial Gain Adjustment Mechanism. Added by Bruce,
- * 2007-02-14.
- */
- bool bDigMechanism; /* TRUE if DIG is enabled, FALSE ow. */
- bool bRegHighPowerMechanism; /* For High Power Mechanism. 061010,
- * by rcnjko.
- */
- u32 FalseAlarmRegValue;
- u8 RegDigOfdmFaUpTh; /* Upper threshold of OFDM false alarm, which is
- * used in DIG.
- */
- u8 DIG_NumberFallbackVote;
- u8 DIG_NumberUpgradeVote;
- /* For HW antenna diversity, added by Roger, 2008.01.30. */
- u32 AdMainAntennaRxOkCnt; /* Main antenna Rx OK count. */
- u32 AdAuxAntennaRxOkCnt; /* Aux antenna Rx OK count. */
- bool bHWAdSwitched; /* TRUE if we has switched default antenna by HW
- * evaluation.
- */
- /* RF High Power upper/lower threshold. */
- u8 RegHiPwrUpperTh;
- u8 RegHiPwrLowerTh;
- /* RF RSSI High Power upper/lower Threshold. */
- u8 RegRSSIHiPwrUpperTh;
- u8 RegRSSIHiPwrLowerTh;
- /* Current CCK RSSI value to determine CCK high power, asked by SD3 DZ,
- * by Bruce, 2007-04-12.
- */
- u8 CurCCKRSSI;
- bool bCurCCKPkt;
- /* High Power Mechanism. Added by amy, 080312. */
- bool bToUpdateTxPwr;
- long UndecoratedSmoothedSS;
- long UndecoratedSmoothedRxPower;
- u8 RSSI;
- char RxPower;
- u8 InitialGain;
- /* For adjust Dig Threshold during Legacy/Leisure Power Save Mode. */
- u32 DozePeriodInPast2Sec;
- /* Don't access BB/RF under disable PLL situation. */
- u8 InitialGainBackUp;
- u8 RegBModeGainStage;
- /* by amy for rate adaptive */
- struct timer_list rateadapter_timer;
- u32 RateAdaptivePeriod;
- bool bEnhanceTxPwr;
- bool bUpdateARFR;
- int ForcedDataRate; /* Force Data Rate. 0: Auto, 0x02: 1M ~ 0x6C: 54M.)
- */
- u32 NumTxUnicast; /* YJ,add,080828,for keep alive. */
- u8 keepAliveLevel; /*YJ,add,080828,for KeepAlive. */
- unsigned long NumTxOkTotal;
- u16 LastRetryCnt;
- u16 LastRetryRate;
- unsigned long LastTxokCnt;
- unsigned long LastRxokCnt;
- u16 CurrRetryCnt;
- unsigned long LastTxOKBytes;
- unsigned long NumTxOkBytesTotal;
- u8 LastFailTxRate;
- long LastFailTxRateSS;
- u8 FailTxRateCount;
- u32 LastTxThroughput;
- /* for up rate. */
- unsigned short bTryuping;
- u8 CurrTxRate; /* the rate before up. */
- u16 CurrRetryRate;
- u16 TryupingCount;
- u8 TryDownCountLowData;
- u8 TryupingCountNoData;
-
- u8 CurrentOperaRate;
- struct work_struct reset_wq;
- struct work_struct watch_dog_wq;
- short ack_tx_to_ieee;
-
- u8 dma_poll_stop_mask;
-
- u16 ShortRetryLimit;
- u16 LongRetryLimit;
- u16 EarlyRxThreshold;
- u32 TransmitConfig;
- u32 ReceiveConfig;
- u32 IntrMask;
-
- struct chnl_access_setting ChannelAccessSetting;
-};
-
-#define MANAGE_PRIORITY 0
-#define BK_PRIORITY 1
-#define BE_PRIORITY 2
-#define VI_PRIORITY 3
-#define VO_PRIORITY 4
-#define HI_PRIORITY 5
-#define BEACON_PRIORITY 6
-
-#define LOW_PRIORITY VI_PRIORITY
-#define NORM_PRIORITY VO_PRIORITY
-/* AC2Queue mapping. */
-#define AC2Q(_ac) (((_ac) == WME_AC_VO) ? VO_PRIORITY : \
- ((_ac) == WME_AC_VI) ? VI_PRIORITY : \
- ((_ac) == WME_AC_BK) ? BK_PRIORITY : \
- BE_PRIORITY)
-
-short rtl8180_tx(struct net_device *dev, u8 *skbuf, int len, int priority,
- bool morefrag, short fragdesc, int rate);
-
-u8 read_nic_byte(struct net_device *dev, int x);
-u32 read_nic_dword(struct net_device *dev, int x);
-u16 read_nic_word(struct net_device *dev, int x);
-void write_nic_byte(struct net_device *dev, int x, u8 y);
-void write_nic_word(struct net_device *dev, int x, u16 y);
-void write_nic_dword(struct net_device *dev, int x, u32 y);
-void force_pci_posting(struct net_device *dev);
-
-void rtl8180_rtx_disable(struct net_device *);
-void rtl8180_set_anaparam(struct net_device *dev, u32 a);
-void rtl8185_set_anaparam2(struct net_device *dev, u32 a);
-void rtl8180_set_hw_wep(struct net_device *dev);
-void rtl8180_no_hw_wep(struct net_device *dev);
-void rtl8180_update_msr(struct net_device *dev);
-void rtl8180_beacon_tx_disable(struct net_device *dev);
-void rtl8180_beacon_rx_disable(struct net_device *dev);
-int rtl8180_down(struct net_device *dev);
-int rtl8180_up(struct net_device *dev);
-void rtl8180_commit(struct net_device *dev);
-void rtl8180_set_chan(struct net_device *dev, short ch);
-void write_phy(struct net_device *dev, u8 adr, u8 data);
-void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
-void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
-void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
-void rtl8185_rf_pins_enable(struct net_device *dev);
-void IPSEnter(struct net_device *dev);
-void IPSLeave(struct net_device *dev);
-int get_curr_tx_free_desc(struct net_device *dev, int priority);
-void UpdateInitialGain(struct net_device *dev);
-bool SetAntennaConfig87SE(struct net_device *dev, u8 DefaultAnt,
- bool bAntDiversity);
-
-void rtl8185b_adapter_start(struct net_device *dev);
-void rtl8185b_rx_enable(struct net_device *dev);
-void rtl8185b_tx_enable(struct net_device *dev);
-void rtl8180_reset(struct net_device *dev);
-void rtl8185b_irq_enable(struct net_device *dev);
-void fix_rx_fifo(struct net_device *dev);
-void fix_tx_fifo(struct net_device *dev);
-void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch);
-void rtl8180_rate_adapter(struct work_struct *work);
-bool MgntActSet_RF_State(struct net_device *dev, enum rt_rf_power_state StateToSet,
- u32 ChangeSource);
-
-#endif
-
-/* fun with the built-in ieee80211 stack... */
-extern int ieee80211_crypto_init(void);
-extern void ieee80211_crypto_deinit(void);
-extern int ieee80211_crypto_tkip_init(void);
-extern void ieee80211_crypto_tkip_exit(void);
-extern int ieee80211_crypto_ccmp_init(void);
-extern void ieee80211_crypto_ccmp_exit(void);
-extern int ieee80211_crypto_wep_init(void);
-extern void ieee80211_crypto_wep_exit(void);
+++ /dev/null
-/*
- This is part of rtl8180 OpenSource driver
- Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
- Released under the terms of GPL (General Public Licence)
-
- Parts of this driver are based on the GPL part of the official realtek driver
- Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
- Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-
- We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
-*/
-
-/*This files contains card eeprom (93c46 or 93c56) programming routines*/
-/*memory is addressed by WORDS*/
-
-#include "r8180.h"
-#include "r8180_hw.h"
-
-#define EPROM_DELAY 10
-
-#define EPROM_ANAPARAM_ADDRLWORD 0xd
-#define EPROM_ANAPARAM_ADDRHWORD 0xe
-
-#define RFCHIPID 0x6
-#define RFCHIPID_INTERSIL 1
-#define RFCHIPID_RFMD 2
-#define RFCHIPID_PHILIPS 3
-#define RFCHIPID_MAXIM 4
-#define RFCHIPID_GCT 5
-#define RFCHIPID_RTL8225 9
-#define RF_ZEBRA2 11
-#define EPROM_TXPW_BASE 0x05
-#define RF_ZEBRA4 12
-#define RFCHIPID_RTL8255 0xa
-#define RF_PARAM 0x19
-#define RF_PARAM_DIGPHY_SHIFT 0
-#define RF_PARAM_ANTBDEFAULT_SHIFT 1
-#define RF_PARAM_CARRIERSENSE_SHIFT 2
-#define RF_PARAM_CARRIERSENSE_MASK (3<<2)
-#define ENERGY_TRESHOLD 0x17
-#define EPROM_VERSION 0x1E
-#define MAC_ADR 0x7
-
-#define CIS 0x18
-
-#define EPROM_TXPW_OFDM_CH1_2 0x20
-
-#define EPROM_TXPW_CH1_2 0x30
-
-#define RTL818X_EEPROM_CMD_READ (1 << 0)
-#define RTL818X_EEPROM_CMD_WRITE (1 << 1)
-#define RTL818X_EEPROM_CMD_CK (1 << 2)
-#define RTL818X_EEPROM_CMD_CS (1 << 3)
-
+++ /dev/null
-/*
- * This is part of rtl818x pci OpenSource driver - v 0.1
- * Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
- * Released under the terms of GPL (General Public License)
- *
- * Parts of this driver are based on the GPL part of the official
- * Realtek driver.
- *
- * Parts of this driver are based on the rtl8180 driver skeleton
- * from Patric Schenke & Andres Salomon.
- *
- * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
- *
- * Parts of BB/RF code are derived from David Young rtl8180 netbsd driver.
- *
- * RSSI calc function from 'The Deuce'
- *
- * Some ideas borrowed from the 8139too.c driver included in linux kernel.
- *
- * We (I?) want to thanks the Authors of those projecs and also the
- * Ndiswrapper's project Authors.
- *
- * A big big thanks goes also to Realtek corp. for their help in my attempt to
- * add RTL8185 and RTL8225 support, and to David Young also.
- *
- * Power management interface routines.
- * Written by Mariusz Matuszek.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#undef RX_DONT_PASS_UL
-#undef DUMMY_RX
-
-#include <linux/slab.h>
-#include <linux/syscalls.h>
-#include <linux/eeprom_93cx6.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-#include "r8180_hw.h"
-#include "r8180.h"
-#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
-#include "r8180_93cx6.h" /* Card EEPROM */
-#include "r8180_wx.h"
-#include "r8180_dm.h"
-
-#include "ieee80211/dot11d.h"
-
-static struct pci_device_id rtl8180_pci_id_tbl[] = {
- {
- .vendor = PCI_VENDOR_ID_REALTEK,
- .device = 0x8199,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .driver_data = 0,
- },
- {
- .vendor = 0,
- .device = 0,
- .subvendor = 0,
- .subdevice = 0,
- .driver_data = 0,
- }
-};
-
-static char ifname[IFNAMSIZ] = "wlan%d";
-static int hwwep;
-
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl);
-MODULE_AUTHOR("Andrea Merello <andrea.merello@gmail.com>");
-MODULE_DESCRIPTION("Linux driver for Realtek RTL8187SE WiFi cards");
-
-module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
-module_param(hwwep, int, S_IRUGO|S_IWUSR);
-
-MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support. Still broken and not available on all cards");
-
-static int rtl8180_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id);
-
-static void rtl8180_pci_remove(struct pci_dev *pdev);
-
-static void rtl8180_shutdown(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- if (dev->netdev_ops->ndo_stop)
- dev->netdev_ops->ndo_stop(dev);
- pci_disable_device(pdev);
-}
-
-static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
-
- if (!netif_running(dev))
- goto out_pci_suspend;
-
- if (dev->netdev_ops->ndo_stop)
- dev->netdev_ops->ndo_stop(dev);
-
- netif_device_detach(dev);
-
-out_pci_suspend:
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
- return 0;
-}
-
-static int rtl8180_resume(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- int err;
- u32 val;
-
- pci_set_power_state(pdev, PCI_D0);
-
- err = pci_enable_device(pdev);
- if (err) {
- dev_err(&pdev->dev, "pci_enable_device failed on resume\n");
-
- return err;
- }
-
- pci_restore_state(pdev);
-
- /*
- * Suspend/Resume resets the PCI configuration space, so we have to
- * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
- * from interfering with C3 CPU state. pci_restore_state won't help
- * here since it only restores the first 64 bytes pci config header.
- */
- pci_read_config_dword(pdev, 0x40, &val);
- if ((val & 0x0000ff00) != 0)
- pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
-
- if (!netif_running(dev))
- goto out;
-
- if (dev->netdev_ops->ndo_open)
- dev->netdev_ops->ndo_open(dev);
-
- netif_device_attach(dev);
-out:
- return 0;
-}
-
-static struct pci_driver rtl8180_pci_driver = {
- .name = RTL8180_MODULE_NAME,
- .id_table = rtl8180_pci_id_tbl,
- .probe = rtl8180_pci_probe,
- .remove = rtl8180_pci_remove,
- .suspend = rtl8180_suspend,
- .resume = rtl8180_resume,
- .shutdown = rtl8180_shutdown,
-};
-
-u8 read_nic_byte(struct net_device *dev, int x)
-{
- return 0xff&readb((u8 __iomem *)dev->mem_start + x);
-}
-
-u32 read_nic_dword(struct net_device *dev, int x)
-{
- return readl((u8 __iomem *)dev->mem_start + x);
-}
-
-u16 read_nic_word(struct net_device *dev, int x)
-{
- return readw((u8 __iomem *)dev->mem_start + x);
-}
-
-void write_nic_byte(struct net_device *dev, int x, u8 y)
-{
- writeb(y, (u8 __iomem *)dev->mem_start + x);
- udelay(20);
-}
-
-void write_nic_dword(struct net_device *dev, int x, u32 y)
-{
- writel(y, (u8 __iomem *)dev->mem_start + x);
- udelay(20);
-}
-
-void write_nic_word(struct net_device *dev, int x, u16 y)
-{
- writew(y, (u8 __iomem *)dev->mem_start + x);
- udelay(20);
-}
-
-inline void force_pci_posting(struct net_device *dev)
-{
- read_nic_byte(dev, EPROM_CMD);
- mb();
-}
-
-static irqreturn_t rtl8180_interrupt(int irq, void *netdev);
-void set_nic_rxring(struct net_device *dev);
-void set_nic_txring(struct net_device *dev);
-static struct net_device_stats *rtl8180_stats(struct net_device *dev);
-void rtl8180_commit(struct net_device *dev);
-void rtl8180_start_tx_beacon(struct net_device *dev);
-
-static struct proc_dir_entry *rtl8180_proc;
-
-static int proc_get_registers(struct seq_file *m, void *v)
-{
- struct net_device *dev = m->private;
- int i, n, max = 0xff;
-
- /* This dump the current register page */
- for (n = 0; n <= max;) {
- seq_printf(m, "\nD: %2x > ", n);
-
- for (i = 0; i < 16 && n <= max; i++, n++)
- seq_printf(m, "%2x ", read_nic_byte(dev, n));
- }
- seq_putc(m, '\n');
- return 0;
-}
-
-int get_curr_tx_free_desc(struct net_device *dev, int priority);
-
-static int proc_get_stats_hw(struct seq_file *m, void *v)
-{
- return 0;
-}
-
-static int proc_get_stats_rx(struct seq_file *m, void *v)
-{
- struct net_device *dev = m->private;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- seq_printf(m,
- "RX OK: %lu\n"
- "RX Retry: %lu\n"
- "RX CRC Error(0-500): %lu\n"
- "RX CRC Error(500-1000): %lu\n"
- "RX CRC Error(>1000): %lu\n"
- "RX ICV Error: %lu\n",
- priv->stats.rxint,
- priv->stats.rxerr,
- priv->stats.rxcrcerrmin,
- priv->stats.rxcrcerrmid,
- priv->stats.rxcrcerrmax,
- priv->stats.rxicverr
- );
-
- return 0;
-}
-
-static int proc_get_stats_tx(struct seq_file *m, void *v)
-{
- struct net_device *dev = m->private;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- unsigned long totalOK;
-
- totalOK = priv->stats.txnpokint + priv->stats.txhpokint +
- priv->stats.txlpokint;
-
- seq_printf(m,
- "TX OK: %lu\n"
- "TX Error: %lu\n"
- "TX Retry: %lu\n"
- "TX beacon OK: %lu\n"
- "TX beacon error: %lu\n",
- totalOK,
- priv->stats.txnperr+priv->stats.txhperr+priv->stats.txlperr,
- priv->stats.txretry,
- priv->stats.txbeacon,
- priv->stats.txbeaconerr
- );
-
- return 0;
-}
-
-static void rtl8180_proc_module_init(void)
-{
- DMESG("Initializing proc filesystem");
- rtl8180_proc = proc_mkdir(RTL8180_MODULE_NAME, init_net.proc_net);
-}
-
-static void rtl8180_proc_module_remove(void)
-{
- remove_proc_entry(RTL8180_MODULE_NAME, init_net.proc_net);
-}
-
-static void rtl8180_proc_remove_one(struct net_device *dev)
-{
- remove_proc_subtree(dev->name, rtl8180_proc);
-}
-
-/*
- * seq_file wrappers for procfile show routines.
- */
-static int rtl8180_proc_open(struct inode *inode, struct file *file)
-{
- struct net_device *dev = proc_get_parent_data(inode);
- int (*show)(struct seq_file *, void *) = PDE_DATA(inode);
-
- return single_open(file, show, dev);
-}
-
-static const struct file_operations rtl8180_proc_fops = {
- .open = rtl8180_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-/*
- * Table of proc files we need to create.
- */
-struct rtl8180_proc_file {
- char name[12];
- int (*show)(struct seq_file *, void *);
-};
-
-static const struct rtl8180_proc_file rtl8180_proc_files[] = {
- { "stats-hw", &proc_get_stats_hw },
- { "stats-rx", &proc_get_stats_rx },
- { "stats-tx", &proc_get_stats_tx },
- { "registers", &proc_get_registers },
- { "" }
-};
-
-static void rtl8180_proc_init_one(struct net_device *dev)
-{
- const struct rtl8180_proc_file *f;
- struct proc_dir_entry *dir;
-
- dir = proc_mkdir_data(dev->name, 0, rtl8180_proc, dev);
- if (!dir) {
- DMESGE("Unable to initialize /proc/net/r8180/%s\n", dev->name);
- return;
- }
-
- for (f = rtl8180_proc_files; f->name[0]; f++) {
- if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir,
- &rtl8180_proc_fops, f->show)) {
- DMESGE("Unable to initialize /proc/net/r8180/%s/%s\n",
- dev->name, f->name);
- return;
- }
- }
-}
-
-/*
- * FIXME: check if we can use some standard already-existent
- * data type+functions in kernel.
- */
-
-static short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
- struct buffer **bufferhead)
-{
- struct buffer *tmp;
-
- if (!*buffer) {
-
- *buffer = kmalloc(sizeof(struct buffer), GFP_KERNEL);
-
- if (*buffer == NULL) {
- DMESGE("Failed to kmalloc head of TX/RX struct");
- return -1;
- }
- (*buffer)->next = *buffer;
- (*buffer)->buf = buf;
- (*buffer)->dma = dma;
- if (bufferhead != NULL)
- (*bufferhead) = (*buffer);
- return 0;
- }
- tmp = *buffer;
-
- while (tmp->next != (*buffer))
- tmp = tmp->next;
- tmp->next = kmalloc(sizeof(struct buffer), GFP_KERNEL);
- if (tmp->next == NULL) {
- DMESGE("Failed to kmalloc TX/RX struct");
- return -1;
- }
- tmp->next->buf = buf;
- tmp->next->dma = dma;
- tmp->next->next = *buffer;
-
- return 0;
-}
-
-static void buffer_free(struct net_device *dev, struct buffer **buffer, int len,
- short consistent)
-{
-
- struct buffer *tmp, *next;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct pci_dev *pdev = priv->pdev;
-
- if (!*buffer)
- return;
-
- tmp = *buffer;
-
- do {
- next = tmp->next;
- if (consistent) {
- pci_free_consistent(pdev, len,
- tmp->buf, tmp->dma);
- } else {
- pci_unmap_single(pdev, tmp->dma,
- len, PCI_DMA_FROMDEVICE);
- kfree(tmp->buf);
- }
- kfree(tmp);
- tmp = next;
- } while (next != *buffer);
-
- *buffer = NULL;
-}
-
-int get_curr_tx_free_desc(struct net_device *dev, int priority)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u32 *tail;
- u32 *head;
- int ret;
-
- switch (priority) {
- case MANAGE_PRIORITY:
- head = priv->txmapringhead;
- tail = priv->txmapringtail;
- break;
- case BK_PRIORITY:
- head = priv->txbkpringhead;
- tail = priv->txbkpringtail;
- break;
- case BE_PRIORITY:
- head = priv->txbepringhead;
- tail = priv->txbepringtail;
- break;
- case VI_PRIORITY:
- head = priv->txvipringhead;
- tail = priv->txvipringtail;
- break;
- case VO_PRIORITY:
- head = priv->txvopringhead;
- tail = priv->txvopringtail;
- break;
- case HI_PRIORITY:
- head = priv->txhpringhead;
- tail = priv->txhpringtail;
- break;
- default:
- return -1;
- }
-
- if (head <= tail)
- ret = priv->txringcount - (tail - head)/8;
- else
- ret = (head - tail)/8;
-
- if (ret > priv->txringcount)
- DMESG("BUG");
-
- return ret;
-}
-
-static short check_nic_enought_desc(struct net_device *dev, int priority)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = netdev_priv(dev);
- int requiredbyte;
- int required;
-
- requiredbyte = priv->ieee80211->fts +
- sizeof(struct ieee80211_header_data);
-
- if (ieee->current_network.QoS_Enable)
- requiredbyte += 2;
-
- required = requiredbyte / (priv->txbuffsize-4);
-
- if (requiredbyte % priv->txbuffsize)
- required++;
-
- /* for now we keep two free descriptor as a safety boundary
- * between the tail and the head
- */
-
- return required + 2 < get_curr_tx_free_desc(dev, priority);
-}
-
-void fix_tx_fifo(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u32 *tmp;
- int i;
-
- for (tmp = priv->txmapring, i = 0;
- i < priv->txringcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
-
- for (tmp = priv->txbkpring, i = 0;
- i < priv->txringcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
-
- for (tmp = priv->txbepring, i = 0;
- i < priv->txringcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
- for (tmp = priv->txvipring, i = 0;
- i < priv->txringcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
-
- for (tmp = priv->txvopring, i = 0;
- i < priv->txringcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
-
- for (tmp = priv->txhpring, i = 0;
- i < priv->txringcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
-
- for (tmp = priv->txbeaconring, i = 0;
- i < priv->txbeaconcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
-
- priv->txmapringtail = priv->txmapring;
- priv->txmapringhead = priv->txmapring;
- priv->txmapbufstail = priv->txmapbufs;
-
- priv->txbkpringtail = priv->txbkpring;
- priv->txbkpringhead = priv->txbkpring;
- priv->txbkpbufstail = priv->txbkpbufs;
-
- priv->txbepringtail = priv->txbepring;
- priv->txbepringhead = priv->txbepring;
- priv->txbepbufstail = priv->txbepbufs;
-
- priv->txvipringtail = priv->txvipring;
- priv->txvipringhead = priv->txvipring;
- priv->txvipbufstail = priv->txvipbufs;
-
- priv->txvopringtail = priv->txvopring;
- priv->txvopringhead = priv->txvopring;
- priv->txvopbufstail = priv->txvopbufs;
-
- priv->txhpringtail = priv->txhpring;
- priv->txhpringhead = priv->txhpring;
- priv->txhpbufstail = priv->txhpbufs;
-
- priv->txbeaconringtail = priv->txbeaconring;
- priv->txbeaconbufstail = priv->txbeaconbufs;
- set_nic_txring(dev);
-
- ieee80211_reset_queue(priv->ieee80211);
- priv->ack_tx_to_ieee = 0;
-}
-
-void fix_rx_fifo(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u32 *tmp;
- struct buffer *rxbuf;
- u8 rx_desc_size;
-
- rx_desc_size = 8; /* 4*8 = 32 bytes */
-
- for (tmp = priv->rxring, rxbuf = priv->rxbufferhead;
- (tmp < (priv->rxring)+(priv->rxringcount)*rx_desc_size);
- tmp += rx_desc_size, rxbuf = rxbuf->next) {
- *(tmp+2) = rxbuf->dma;
- *tmp = *tmp & ~0xfff;
- *tmp = *tmp | priv->rxbuffersize;
- *tmp |= (1<<31);
- }
-
- priv->rxringtail = priv->rxring;
- priv->rxbuffer = priv->rxbufferhead;
- priv->rx_skb_complete = 1;
- set_nic_rxring(dev);
-}
-
-static void rtl8180_irq_disable(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- write_nic_dword(dev, IMR, 0);
- force_pci_posting(dev);
- priv->irq_enabled = 0;
-}
-
-void rtl8180_set_mode(struct net_device *dev, int mode)
-{
- u8 ecmd;
-
- ecmd = read_nic_byte(dev, EPROM_CMD);
- ecmd = ecmd & ~EPROM_CMD_OPERATING_MODE_MASK;
- ecmd = ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
- ecmd = ecmd & ~(1<<EPROM_CS_SHIFT);
- ecmd = ecmd & ~(1<<EPROM_CK_SHIFT);
- write_nic_byte(dev, EPROM_CMD, ecmd);
-}
-
-void rtl8180_beacon_tx_enable(struct net_device *dev);
-
-void rtl8180_update_msr(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 msr;
- u32 rxconf;
-
- msr = read_nic_byte(dev, MSR);
- msr &= ~MSR_LINK_MASK;
-
- rxconf = read_nic_dword(dev, RX_CONF);
-
- if (priv->ieee80211->state == IEEE80211_LINKED) {
- if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
- else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
- msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
- else if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
- msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
- else
- msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
- rxconf |= (1<<RX_CHECK_BSSID_SHIFT);
-
- } else {
- msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
- rxconf &= ~(1<<RX_CHECK_BSSID_SHIFT);
- }
-
- write_nic_byte(dev, MSR, msr);
- write_nic_dword(dev, RX_CONF, rxconf);
-}
-
-void rtl8180_set_chan(struct net_device *dev, short ch)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- if ((ch > 14) || (ch < 1)) {
- netdev_err(dev, "In %s: Invalid channel %d\n", __func__, ch);
- return;
- }
-
- priv->chan = ch;
- priv->rf_set_chan(dev, priv->chan);
-}
-
-void set_nic_txring(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- write_nic_dword(dev, TX_MANAGEPRIORITY_RING_ADDR, priv->txmapringdma);
- write_nic_dword(dev, TX_BKPRIORITY_RING_ADDR, priv->txbkpringdma);
- write_nic_dword(dev, TX_BEPRIORITY_RING_ADDR, priv->txbepringdma);
- write_nic_dword(dev, TX_VIPRIORITY_RING_ADDR, priv->txvipringdma);
- write_nic_dword(dev, TX_VOPRIORITY_RING_ADDR, priv->txvopringdma);
- write_nic_dword(dev, TX_HIGHPRIORITY_RING_ADDR, priv->txhpringdma);
- write_nic_dword(dev, TX_BEACON_RING_ADDR, priv->txbeaconringdma);
-}
-
-void rtl8180_beacon_tx_enable(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ);
- write_nic_byte(dev, TPPollStop, priv->dma_poll_mask);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-void rtl8180_beacon_tx_disable(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- priv->dma_poll_stop_mask |= TPPOLLSTOP_BQ;
- write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
-}
-
-void rtl8180_rtx_disable(struct net_device *dev)
-{
- u8 cmd;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- cmd = read_nic_byte(dev, CMD);
- write_nic_byte(dev, CMD, cmd &
- ~((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
- force_pci_posting(dev);
- mdelay(10);
-
- if (!priv->rx_skb_complete)
- dev_kfree_skb_any(priv->rx_skb);
-}
-
-static short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
- int addr)
-{
- int i;
- u32 *desc;
- u32 *tmp;
- dma_addr_t dma_desc, dma_tmp;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct pci_dev *pdev = priv->pdev;
- void *buf;
-
- if ((bufsize & 0xfff) != bufsize) {
- DMESGE("TX buffer allocation too large");
- return 0;
- }
- desc = (u32 *)pci_alloc_consistent(pdev,
- sizeof(u32)*8*count+256, &dma_desc);
- if (desc == NULL)
- return -1;
-
- if (dma_desc & 0xff)
- /*
- * descriptor's buffer must be 256 byte aligned
- * we shouldn't be here, since we set DMA mask !
- */
- WARN(1, "DMA buffer is not aligned\n");
-
- tmp = desc;
-
- for (i = 0; i < count; i++) {
- buf = (void *)pci_alloc_consistent(pdev, bufsize, &dma_tmp);
- if (buf == NULL)
- return -ENOMEM;
-
- switch (addr) {
- case TX_MANAGEPRIORITY_RING_ADDR:
- if (-1 == buffer_add(&priv->txmapbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer NP");
- return -ENOMEM;
- }
- break;
- case TX_BKPRIORITY_RING_ADDR:
- if (-1 == buffer_add(&priv->txbkpbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer LP");
- return -ENOMEM;
- }
- break;
- case TX_BEPRIORITY_RING_ADDR:
- if (-1 == buffer_add(&priv->txbepbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer NP");
- return -ENOMEM;
- }
- break;
- case TX_VIPRIORITY_RING_ADDR:
- if (-1 == buffer_add(&priv->txvipbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer LP");
- return -ENOMEM;
- }
- break;
- case TX_VOPRIORITY_RING_ADDR:
- if (-1 == buffer_add(&priv->txvopbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer NP");
- return -ENOMEM;
- }
- break;
- case TX_HIGHPRIORITY_RING_ADDR:
- if (-1 == buffer_add(&priv->txhpbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer HP");
- return -ENOMEM;
- }
- break;
- case TX_BEACON_RING_ADDR:
- if (-1 == buffer_add(&priv->txbeaconbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer BP");
- return -ENOMEM;
- }
- break;
- }
- *tmp = *tmp & ~(1<<31); /* descriptor empty, owned by the drv */
- *(tmp+2) = (u32)dma_tmp;
- *(tmp+3) = bufsize;
-
- if (i+1 < count)
- *(tmp+4) = (u32)dma_desc+((i+1)*8*4);
- else
- *(tmp+4) = (u32)dma_desc;
-
- tmp = tmp+8;
- }
-
- switch (addr) {
- case TX_MANAGEPRIORITY_RING_ADDR:
- priv->txmapringdma = dma_desc;
- priv->txmapring = desc;
- break;
- case TX_BKPRIORITY_RING_ADDR:
- priv->txbkpringdma = dma_desc;
- priv->txbkpring = desc;
- break;
- case TX_BEPRIORITY_RING_ADDR:
- priv->txbepringdma = dma_desc;
- priv->txbepring = desc;
- break;
- case TX_VIPRIORITY_RING_ADDR:
- priv->txvipringdma = dma_desc;
- priv->txvipring = desc;
- break;
- case TX_VOPRIORITY_RING_ADDR:
- priv->txvopringdma = dma_desc;
- priv->txvopring = desc;
- break;
- case TX_HIGHPRIORITY_RING_ADDR:
- priv->txhpringdma = dma_desc;
- priv->txhpring = desc;
- break;
- case TX_BEACON_RING_ADDR:
- priv->txbeaconringdma = dma_desc;
- priv->txbeaconring = desc;
- break;
-
- }
-
- return 0;
-}
-
-static void free_tx_desc_rings(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct pci_dev *pdev = priv->pdev;
- int count = priv->txringcount;
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txmapring, priv->txmapringdma);
- buffer_free(dev, &(priv->txmapbufs), priv->txbuffsize, 1);
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txbkpring, priv->txbkpringdma);
- buffer_free(dev, &(priv->txbkpbufs), priv->txbuffsize, 1);
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txbepring, priv->txbepringdma);
- buffer_free(dev, &(priv->txbepbufs), priv->txbuffsize, 1);
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txvipring, priv->txvipringdma);
- buffer_free(dev, &(priv->txvipbufs), priv->txbuffsize, 1);
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txvopring, priv->txvopringdma);
- buffer_free(dev, &(priv->txvopbufs), priv->txbuffsize, 1);
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txhpring, priv->txhpringdma);
- buffer_free(dev, &(priv->txhpbufs), priv->txbuffsize, 1);
-
- count = priv->txbeaconcount;
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txbeaconring, priv->txbeaconringdma);
- buffer_free(dev, &(priv->txbeaconbufs), priv->txbuffsize, 1);
-}
-
-static void free_rx_desc_ring(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct pci_dev *pdev = priv->pdev;
- int count = priv->rxringcount;
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->rxring, priv->rxringdma);
-
- buffer_free(dev, &(priv->rxbuffer), priv->rxbuffersize, 0);
-}
-
-static short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
-{
- int i;
- u32 *desc;
- u32 *tmp;
- dma_addr_t dma_desc, dma_tmp;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct pci_dev *pdev = priv->pdev;
- void *buf;
- u8 rx_desc_size;
-
- rx_desc_size = 8; /* 4*8 = 32 bytes */
-
- if ((bufsize & 0xfff) != bufsize) {
- DMESGE("RX buffer allocation too large");
- return -1;
- }
-
- desc = (u32 *)pci_alloc_consistent(pdev,
- sizeof(u32) * rx_desc_size * count + 256, &dma_desc);
-
- if (dma_desc & 0xff)
- /*
- * descriptor's buffer must be 256 byte aligned
- * should never happen since we specify the DMA mask
- */
- WARN(1, "DMA buffer is not aligned\n");
-
- priv->rxring = desc;
- priv->rxringdma = dma_desc;
- tmp = desc;
-
- for (i = 0; i < count; i++) {
- buf = kmalloc(bufsize * sizeof(u8), GFP_ATOMIC);
- if (buf == NULL) {
- DMESGE("Failed to kmalloc RX buffer");
- return -1;
- }
-
- dma_tmp = pci_map_single(pdev, buf, bufsize * sizeof(u8),
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, dma_tmp))
- return -1;
- if (-1 == buffer_add(&(priv->rxbuffer), buf, dma_tmp,
- &(priv->rxbufferhead))) {
- DMESGE("Unable to allocate mem RX buf");
- return -1;
- }
- *tmp = 0; /* zero pads the header of the descriptor */
- *tmp = *tmp | (bufsize&0xfff);
- *(tmp+2) = (u32)dma_tmp;
- *tmp = *tmp | (1<<31); /* descriptor void, owned by the NIC */
-
- tmp = tmp+rx_desc_size;
- }
-
- /* this is the last descriptor */
- *(tmp - rx_desc_size) = *(tmp - rx_desc_size) | (1 << 30);
-
- return 0;
-}
-
-
-void set_nic_rxring(struct net_device *dev)
-{
- u8 pgreg;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- pgreg = read_nic_byte(dev, PGSELECT);
- write_nic_byte(dev, PGSELECT, pgreg & ~(1<<PGSELECT_PG_SHIFT));
-
- write_nic_dword(dev, RXRING_ADDR, priv->rxringdma);
-}
-
-void rtl8180_reset(struct net_device *dev)
-{
- u8 cr;
-
- rtl8180_irq_disable(dev);
-
- cr = read_nic_byte(dev, CMD);
- cr = cr & 2;
- cr = cr | (1<<CMD_RST_SHIFT);
- write_nic_byte(dev, CMD, cr);
-
- force_pci_posting(dev);
-
- mdelay(200);
-
- if (read_nic_byte(dev, CMD) & (1<<CMD_RST_SHIFT))
- DMESGW("Card reset timeout!");
- else
- DMESG("Card successfully reset");
-
- rtl8180_set_mode(dev, EPROM_CMD_LOAD);
- force_pci_posting(dev);
- mdelay(200);
-}
-
-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, 720};
-
-inline u16 rtl8180_rate2rate(short rate)
-{
- if (rate > 12)
- return 10;
- return rtl_rate[rate];
-}
-
-inline u8 rtl8180_IsWirelessBMode(u16 rate)
-{
- if (((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220))
- return 1;
- else
- return 0;
-}
-
-u16 N_DBPSOfRate(u16 DataRate);
-
-static u16 ComputeTxTime(u16 FrameLength, u16 DataRate, u8 bManagementFrame,
- u8 bShortPreamble)
-{
- u16 FrameTime;
- u16 N_DBPS;
- u16 Ceiling;
-
- if (rtl8180_IsWirelessBMode(DataRate)) {
- if (bManagementFrame || !bShortPreamble || DataRate == 10)
- /* long preamble */
- FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
- else
- /* short preamble */
- FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
-
- if ((FrameLength*8 % (DataRate/10)) != 0) /* get the ceilling */
- FrameTime++;
- } else { /* 802.11g DSSS-OFDM PLCP length field calculation. */
- N_DBPS = N_DBPSOfRate(DataRate);
- Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
- + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
- FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
- }
- return FrameTime;
-}
-
-u16 N_DBPSOfRate(u16 DataRate)
-{
- u16 N_DBPS = 24;
-
- switch (DataRate) {
- case 60:
- N_DBPS = 24;
- break;
- case 90:
- N_DBPS = 36;
- break;
- case 120:
- N_DBPS = 48;
- break;
- case 180:
- N_DBPS = 72;
- break;
- case 240:
- N_DBPS = 96;
- break;
- case 360:
- N_DBPS = 144;
- break;
- case 480:
- N_DBPS = 192;
- break;
- case 540:
- N_DBPS = 216;
- break;
- default:
- break;
- }
-
- return N_DBPS;
-}
-
-/*
- * For Netgear case, they want good-looking signal strength.
- */
-static long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
-{
- long RetSS;
-
- /* Step 1. Scale mapping. */
- if (CurrSS >= 71 && CurrSS <= 100)
- RetSS = 90 + ((CurrSS - 70) / 3);
- else if (CurrSS >= 41 && CurrSS <= 70)
- RetSS = 78 + ((CurrSS - 40) / 3);
- else if (CurrSS >= 31 && CurrSS <= 40)
- RetSS = 66 + (CurrSS - 30);
- else if (CurrSS >= 21 && CurrSS <= 30)
- RetSS = 54 + (CurrSS - 20);
- else if (CurrSS >= 5 && CurrSS <= 20)
- RetSS = 42 + (((CurrSS - 5) * 2) / 3);
- else if (CurrSS == 4)
- RetSS = 36;
- else if (CurrSS == 3)
- RetSS = 27;
- else if (CurrSS == 2)
- RetSS = 18;
- else if (CurrSS == 1)
- RetSS = 9;
- else
- RetSS = CurrSS;
-
- /* Step 2. Smoothing. */
- if (LastSS > 0)
- RetSS = ((LastSS * 5) + (RetSS) + 5) / 6;
-
- return RetSS;
-}
-
-/*
- * Translate 0-100 signal strength index into dBm.
- */
-static long TranslateToDbm8185(u8 SignalStrengthIndex)
-{
- long SignalPower;
-
- /* Translate to dBm (x=0.5y-95). */
- SignalPower = (long)((SignalStrengthIndex + 1) >> 1);
- SignalPower -= 95;
-
- return SignalPower;
-}
-
-/*
- * Perform signal smoothing for dynamic mechanism.
- * This is different with PerformSignalSmoothing8185 in smoothing formula.
- * No dramatic adjustment is applied because dynamic mechanism need some
- * degree of correctness. Ported from 8187B.
- */
-static void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
- bool bCckRate)
-{
- long smoothedSS;
- long smoothedRx;
-
- /* Determine the current packet is CCK rate. */
- priv->bCurCCKPkt = bCckRate;
-
- smoothedSS = priv->SignalStrength * 10;
-
- if (priv->UndecoratedSmoothedSS >= 0)
- smoothedSS = ((priv->UndecoratedSmoothedSS * 5) +
- smoothedSS) / 6;
-
- priv->UndecoratedSmoothedSS = smoothedSS;
-
- smoothedRx = ((priv->UndecoratedSmoothedRxPower * 50) +
- (priv->RxPower * 11)) / 60;
-
- priv->UndecoratedSmoothedRxPower = smoothedRx;
-
- if (bCckRate)
- priv->CurCCKRSSI = priv->RSSI;
- else
- priv->CurCCKRSSI = 0;
-}
-
-
-/*
- * This is rough RX isr handling routine
- */
-static void rtl8180_rx(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct sk_buff *tmp_skb;
- short first, last;
- u32 len;
- int lastlen;
- unsigned char quality, signal;
- u8 rate;
- u32 *tmp, *tmp2;
- u8 rx_desc_size;
- u8 padding;
- char rxpower = 0;
- u32 RXAGC = 0;
- long RxAGC_dBm = 0;
- u8 LNA = 0, BB = 0;
- u8 LNA_gain[4] = {02, 17, 29, 39};
- u8 Antenna = 0;
- struct ieee80211_hdr_4addr *hdr;
- u16 fc, type;
- u8 bHwError = 0, bCRC = 0, bICV = 0;
- bool bCckRate = false;
- u8 RSSI = 0;
- long SignalStrengthIndex = 0;
- struct ieee80211_rx_stats stats = {
- .signal = 0,
- .noise = -98,
- .rate = 0,
- .freq = IEEE80211_24GHZ_BAND,
- };
-
- stats.nic_type = NIC_8185B;
- rx_desc_size = 8;
-
- if ((*(priv->rxringtail)) & (1<<31)) {
- /* we have got an RX int, but the descriptor. we are pointing
- * is empty.
- */
-
- priv->stats.rxnodata++;
- priv->ieee80211->stats.rx_errors++;
-
- tmp2 = NULL;
- tmp = priv->rxringtail;
- do {
- if (tmp == priv->rxring)
- tmp = priv->rxring + (priv->rxringcount - 1) *
- rx_desc_size;
- else
- tmp -= rx_desc_size;
-
- if (!(*tmp & (1<<31)))
- tmp2 = tmp;
- } while (tmp != priv->rxring);
-
- if (tmp2)
- priv->rxringtail = tmp2;
- }
-
- /* while there are filled descriptors */
- while (!(*(priv->rxringtail) & (1<<31))) {
- if (*(priv->rxringtail) & (1<<26))
- DMESGW("RX buffer overflow");
- if (*(priv->rxringtail) & (1<<12))
- priv->stats.rxicverr++;
-
- if (*(priv->rxringtail) & (1<<27)) {
- priv->stats.rxdmafail++;
- goto drop;
- }
-
- pci_dma_sync_single_for_cpu(priv->pdev,
- priv->rxbuffer->dma,
- priv->rxbuffersize * sizeof(u8),
- PCI_DMA_FROMDEVICE);
-
- first = *(priv->rxringtail) & (1<<29) ? 1 : 0;
- if (first)
- priv->rx_prevlen = 0;
-
- last = *(priv->rxringtail) & (1<<28) ? 1 : 0;
- if (last) {
- lastlen = ((*priv->rxringtail) & 0xfff);
-
- /* if the last descriptor (that should tell us the total
- * packet len) tell us something less than the
- * descriptors len we had until now, then there is some
- * problem..
- * workaround to prevent kernel panic
- */
- if (lastlen < priv->rx_prevlen)
- len = 0;
- else
- len = lastlen-priv->rx_prevlen;
-
- if (*(priv->rxringtail) & (1<<13)) {
- if ((*(priv->rxringtail) & 0xfff) < 500)
- priv->stats.rxcrcerrmin++;
- else if ((*(priv->rxringtail) & 0x0fff) > 1000)
- priv->stats.rxcrcerrmax++;
- else
- priv->stats.rxcrcerrmid++;
-
- }
-
- } else {
- len = priv->rxbuffersize;
- }
-
- if (first && last) {
- padding = ((*(priv->rxringtail+3))&(0x04000000))>>26;
- } else if (first) {
- padding = ((*(priv->rxringtail+3))&(0x04000000))>>26;
- if (padding)
- len -= 2;
- } else {
- padding = 0;
- }
- padding = 0;
- priv->rx_prevlen += len;
-
- if (priv->rx_prevlen > MAX_FRAG_THRESHOLD + 100) {
- /* HW is probably passing several buggy frames without
- * FD or LD flag set.
- * Throw this garbage away to prevent skb memory
- * exhausting
- */
- if (!priv->rx_skb_complete)
- dev_kfree_skb_any(priv->rx_skb);
- priv->rx_skb_complete = 1;
- }
-
- signal = (unsigned char)((*(priv->rxringtail + 3) &
- 0x00ff0000) >> 16);
- signal = (signal & 0xfe) >> 1;
-
- quality = (unsigned char)((*(priv->rxringtail+3)) & (0xff));
-
- stats.mac_time[0] = *(priv->rxringtail+1);
- stats.mac_time[1] = *(priv->rxringtail+2);
-
- rxpower = ((char)((*(priv->rxringtail + 4) &
- 0x00ff0000) >> 16)) / 2 - 42;
-
- RSSI = ((u8)((*(priv->rxringtail + 3) &
- 0x0000ff00) >> 8)) & 0x7f;
-
- rate = ((*(priv->rxringtail)) &
- ((1<<23)|(1<<22)|(1<<21)|(1<<20)))>>20;
-
- stats.rate = rtl8180_rate2rate(rate);
- Antenna = (*(priv->rxringtail + 3) & 0x00008000) == 0 ? 0 : 1;
- if (!rtl8180_IsWirelessBMode(stats.rate)) { /* OFDM rate. */
- RxAGC_dBm = rxpower+1; /* bias */
- } else { /* CCK rate. */
- RxAGC_dBm = signal; /* bit 0 discard */
-
- LNA = (u8) (RxAGC_dBm & 0x60) >> 5; /* bit 6~ bit 5 */
- BB = (u8) (RxAGC_dBm & 0x1F); /* bit 4 ~ bit 0 */
-
- /* Pin_11b=-(LNA_gain+BB_gain) (dBm) */
- RxAGC_dBm = -(LNA_gain[LNA] + (BB * 2));
-
- RxAGC_dBm += 4; /* bias */
- }
-
- if (RxAGC_dBm & 0x80) /* absolute value */
- RXAGC = ~(RxAGC_dBm)+1;
- bCckRate = rtl8180_IsWirelessBMode(stats.rate);
- /* Translate RXAGC into 1-100. */
- if (!rtl8180_IsWirelessBMode(stats.rate)) { /* OFDM rate. */
- if (RXAGC > 90)
- RXAGC = 90;
- else if (RXAGC < 25)
- RXAGC = 25;
- RXAGC = (90-RXAGC)*100/65;
- } else { /* CCK rate. */
- if (RXAGC > 95)
- RXAGC = 95;
- else if (RXAGC < 30)
- RXAGC = 30;
- RXAGC = (95-RXAGC)*100/65;
- }
- priv->SignalStrength = (u8)RXAGC;
- priv->RecvSignalPower = RxAGC_dBm;
- priv->RxPower = rxpower;
- priv->RSSI = RSSI;
- /* SQ translation formula is provided by SD3 DZ. 2006.06.27 */
- if (quality >= 127)
- /* 0 causes epc to show signal zero, walk around now */
- quality = 1;
- else if (quality < 27)
- quality = 100;
- else
- quality = 127 - quality;
- priv->SignalQuality = quality;
-
- stats.signal = (u8) quality;
-
- stats.signalstrength = RXAGC;
- if (stats.signalstrength > 100)
- stats.signalstrength = 100;
- stats.signalstrength = (stats.signalstrength * 70) / 100 + 30;
- stats.rssi = priv->wstats.qual.qual = priv->SignalQuality;
- stats.noise = priv->wstats.qual.noise =
- 100 - priv->wstats.qual.qual;
- bHwError = (((*(priv->rxringtail)) & (0x00000fff)) == 4080) |
- (((*(priv->rxringtail)) & (0x04000000)) != 0) |
- (((*(priv->rxringtail)) & (0x08000000)) != 0) |
- (((~(*(priv->rxringtail))) & (0x10000000)) != 0) |
- (((~(*(priv->rxringtail))) & (0x20000000)) != 0);
- bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13;
- bICV = ((*(priv->rxringtail)) & (0x00001000)) >> 12;
- hdr = (struct ieee80211_hdr_4addr *)priv->rxbuffer->buf;
- fc = le16_to_cpu(hdr->frame_ctl);
- type = WLAN_FC_GET_TYPE(fc);
-
- if (IEEE80211_FTYPE_CTL != type &&
- !bHwError && !bCRC && !bICV &&
- eqMacAddr(priv->ieee80211->current_network.bssid,
- fc & IEEE80211_FCTL_TODS ? hdr->addr1 :
- fc & IEEE80211_FCTL_FROMDS ? hdr->addr2 :
- hdr->addr3)) {
-
- /* Perform signal smoothing for dynamic
- * mechanism on demand. This is different
- * with PerformSignalSmoothing8185 in smoothing
- * fomula. No dramatic adjustion is apply
- * because dynamic mechanism need some degree
- * of correctness. */
- PerformUndecoratedSignalSmoothing8185(priv, bCckRate);
-
- /* For good-looking singal strength. */
- SignalStrengthIndex = NetgearSignalStrengthTranslate(
- priv->LastSignalStrengthInPercent,
- priv->SignalStrength);
-
- priv->LastSignalStrengthInPercent = SignalStrengthIndex;
- priv->Stats_SignalStrength =
- TranslateToDbm8185((u8)SignalStrengthIndex);
-
- /*
- * We need more correct power of received packets and
- * the "SignalStrength" of RxStats is beautified, so we
- * record the correct power here.
- */
-
- priv->Stats_SignalQuality = (long)(
- priv->Stats_SignalQuality * 5 +
- (long)priv->SignalQuality + 5) / 6;
-
- priv->Stats_RecvSignalPower = (long)(
- priv->Stats_RecvSignalPower * 5 +
- priv->RecvSignalPower - 1) / 6;
-
- /*
- * Figure out which antenna received the last packet.
- * 0: aux, 1: main
- */
- priv->LastRxPktAntenna = Antenna ? 1 : 0;
- SwAntennaDiversityRxOk8185(dev, priv->SignalStrength);
- }
-
- if (first) {
- if (!priv->rx_skb_complete) {
- /* seems that HW sometimes fails to receive and
- * doesn't provide the last descriptor.
- */
- dev_kfree_skb_any(priv->rx_skb);
- priv->stats.rxnolast++;
- }
- priv->rx_skb = dev_alloc_skb(len+2);
- if (!priv->rx_skb)
- goto drop;
-
- priv->rx_skb_complete = 0;
- priv->rx_skb->dev = dev;
- } else {
- /* if we are here we should have already RXed the first
- * frame.
- * If we get here and the skb is not allocated then
- * we have just throw out garbage (skb not allocated)
- * and we are still rxing garbage....
- */
- if (!priv->rx_skb_complete) {
-
- tmp_skb = dev_alloc_skb(
- priv->rx_skb->len + len + 2);
-
- if (!tmp_skb)
- goto drop;
-
- tmp_skb->dev = dev;
-
- memcpy(skb_put(tmp_skb, priv->rx_skb->len),
- priv->rx_skb->data,
- priv->rx_skb->len);
-
- dev_kfree_skb_any(priv->rx_skb);
-
- priv->rx_skb = tmp_skb;
- }
- }
-
- if (!priv->rx_skb_complete) {
- memcpy(skb_put(priv->rx_skb, len), ((unsigned char *)
- priv->rxbuffer->buf) + (padding ? 2 : 0), len);
- }
-
- if (last && !priv->rx_skb_complete) {
- if (priv->rx_skb->len > 4)
- skb_trim(priv->rx_skb, priv->rx_skb->len-4);
- if (!ieee80211_rtl_rx(priv->ieee80211,
- priv->rx_skb, &stats))
- dev_kfree_skb_any(priv->rx_skb);
- priv->rx_skb_complete = 1;
- }
-
- pci_dma_sync_single_for_device(priv->pdev,
- priv->rxbuffer->dma,
- priv->rxbuffersize * sizeof(u8),
- PCI_DMA_FROMDEVICE);
-
-drop: /* this is used when we have not enough mem */
- /* restore the descriptor */
- *(priv->rxringtail+2) = priv->rxbuffer->dma;
- *(priv->rxringtail) = *(priv->rxringtail) & ~0xfff;
- *(priv->rxringtail) =
- *(priv->rxringtail) | priv->rxbuffersize;
-
- *(priv->rxringtail) =
- *(priv->rxringtail) | (1<<31);
-
- priv->rxringtail += rx_desc_size;
- if (priv->rxringtail >=
- (priv->rxring)+(priv->rxringcount)*rx_desc_size)
- priv->rxringtail = priv->rxring;
-
- priv->rxbuffer = (priv->rxbuffer->next);
- }
-}
-
-
-static void rtl8180_dma_kick(struct net_device *dev, int priority)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- write_nic_byte(dev, TX_DMA_POLLING,
- (1 << (priority + 1)) | priv->dma_poll_mask);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
- force_pci_posting(dev);
-}
-
-static void rtl8180_data_hard_stop(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- priv->dma_poll_stop_mask |= TPPOLLSTOP_AC_VIQ;
- write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-static void rtl8180_data_hard_resume(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_AC_VIQ);
- write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-/*
- * This function TX data frames when the ieee80211 stack requires this.
- * It checks also if we need to stop the ieee tx queue, eventually do it
- */
-static void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
- int rate)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- int mode;
- struct ieee80211_hdr_3addr *h = (struct ieee80211_hdr_3addr *)skb->data;
- bool morefrag = le16_to_cpu(h->frame_control) & IEEE80211_FCTL_MOREFRAGS;
- unsigned long flags;
- int priority;
-
- mode = priv->ieee80211->iw_mode;
-
- rate = ieeerate2rtlrate(rate);
- /*
- * This function doesn't require lock because we make sure it's called
- * with the tx_lock already acquired.
- * This come from the kernel's hard_xmit callback (through the ieee
- * stack, or from the try_wake_queue (again through the ieee stack.
- */
- priority = AC2Q(skb->priority);
- spin_lock_irqsave(&priv->tx_lock, flags);
-
- if (priv->ieee80211->bHwRadioOff) {
- spin_unlock_irqrestore(&priv->tx_lock, flags);
-
- return;
- }
-
- if (!check_nic_enought_desc(dev, priority)) {
- DMESGW("Error: no descriptor left by previous TX (avail %d) ",
- get_curr_tx_free_desc(dev, priority));
- ieee80211_rtl_stop_queue(priv->ieee80211);
- }
- rtl8180_tx(dev, skb->data, skb->len, priority, morefrag, 0, rate);
- if (!check_nic_enought_desc(dev, priority))
- ieee80211_rtl_stop_queue(priv->ieee80211);
-
- spin_unlock_irqrestore(&priv->tx_lock, flags);
-}
-
-/*
- * This is a rough attempt to TX a frame
- * This is called by the ieee 80211 stack to TX management frames.
- * If the ring is full packets are dropped (for data frame the queue
- * is stopped before this can happen). For this reason it is better
- * if the descriptors are larger than the largest management frame
- * we intend to TX: i'm unsure what the HW does if it will not find
- * the last fragment of a frame because it has been dropped...
- * Since queues for Management and Data frames are different we
- * might use a different lock than tx_lock (for example mgmt_tx_lock)
- */
-/* these function may loop if invoked with 0 descriptors or 0 len buffer */
-static int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- unsigned long flags;
- int priority;
-
- priority = MANAGE_PRIORITY;
-
- spin_lock_irqsave(&priv->tx_lock, flags);
-
- if (priv->ieee80211->bHwRadioOff) {
- spin_unlock_irqrestore(&priv->tx_lock, flags);
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
-
- rtl8180_tx(dev, skb->data, skb->len, priority,
- 0, 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
-
- priv->ieee80211->stats.tx_bytes += skb->len;
- priv->ieee80211->stats.tx_packets++;
- spin_unlock_irqrestore(&priv->tx_lock, flags);
-
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
-}
-
-static void rtl8180_prepare_beacon(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct sk_buff *skb;
-
- u16 word = read_nic_word(dev, BcnItv);
- word &= ~BcnItv_BcnItv; /* clear Bcn_Itv */
-
- /* word |= 0x64; */
- word |= cpu_to_le16(priv->ieee80211->current_network.beacon_interval);
-
- write_nic_word(dev, BcnItv, word);
-
- skb = ieee80211_get_beacon(priv->ieee80211);
- if (skb) {
- rtl8180_tx(dev, skb->data, skb->len, BEACON_PRIORITY,
- 0, 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
- dev_kfree_skb_any(skb);
- }
-}
-
-/*
- * This function do the real dirty work: it enqueues a TX command descriptor in
- * the ring buffer, copyes the frame in a TX buffer and kicks the NIC to ensure
- * it does the DMA transfer.
- */
-short rtl8180_tx(struct net_device *dev, u8 *txbuf, int len, int priority,
- bool morefrag, short descfrag, int rate)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u32 *tail, *temp_tail;
- u32 *begin;
- u32 *buf;
- int i;
- int remain;
- int buflen;
- int count;
- struct buffer *buflist;
- struct ieee80211_hdr_3addr *frag_hdr =
- (struct ieee80211_hdr_3addr *)txbuf;
- u8 dest[ETH_ALEN];
- u8 bUseShortPreamble = 0;
- u8 bCTSEnable = 0;
- u8 bRTSEnable = 0;
- u16 Duration = 0;
- u16 RtsDur = 0;
- u16 ThisFrameTime = 0;
- u16 TxDescDuration = 0;
- bool ownbit_flag = false;
-
- switch (priority) {
- case MANAGE_PRIORITY:
- tail = priv->txmapringtail;
- begin = priv->txmapring;
- buflist = priv->txmapbufstail;
- count = priv->txringcount;
- break;
- case BK_PRIORITY:
- tail = priv->txbkpringtail;
- begin = priv->txbkpring;
- buflist = priv->txbkpbufstail;
- count = priv->txringcount;
- break;
- case BE_PRIORITY:
- tail = priv->txbepringtail;
- begin = priv->txbepring;
- buflist = priv->txbepbufstail;
- count = priv->txringcount;
- break;
- case VI_PRIORITY:
- tail = priv->txvipringtail;
- begin = priv->txvipring;
- buflist = priv->txvipbufstail;
- count = priv->txringcount;
- break;
- case VO_PRIORITY:
- tail = priv->txvopringtail;
- begin = priv->txvopring;
- buflist = priv->txvopbufstail;
- count = priv->txringcount;
- break;
- case HI_PRIORITY:
- tail = priv->txhpringtail;
- begin = priv->txhpring;
- buflist = priv->txhpbufstail;
- count = priv->txringcount;
- break;
- case BEACON_PRIORITY:
- tail = priv->txbeaconringtail;
- begin = priv->txbeaconring;
- buflist = priv->txbeaconbufstail;
- count = priv->txbeaconcount;
- break;
- default:
- return -1;
- break;
- }
-
- memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
- if (is_multicast_ether_addr(dest)) {
- Duration = 0;
- RtsDur = 0;
- bRTSEnable = 0;
- bCTSEnable = 0;
-
- ThisFrameTime = ComputeTxTime(len + sCrcLng,
- rtl8180_rate2rate(rate), 0, bUseShortPreamble);
- TxDescDuration = ThisFrameTime;
- } else { /* Unicast packet */
- u16 AckTime;
-
- /* for Keep alive */
- priv->NumTxUnicast++;
-
- /* Figure out ACK rate according to BSS basic rate
- * and Tx rate.
- * AckCTSLng = 14 use 1M bps send
- */
- AckTime = ComputeTxTime(14, 10, 0, 0);
-
- if (((len + sCrcLng) > priv->rts) && priv->rts) { /* RTS/CTS. */
- u16 RtsTime, CtsTime;
- bRTSEnable = 1;
- bCTSEnable = 0;
-
- /* Rate and time required for RTS. */
- RtsTime = ComputeTxTime(sAckCtsLng / 8,
- priv->ieee80211->basic_rate, 0, 0);
-
- /* Rate and time required for CTS.
- * AckCTSLng = 14 use 1M bps send
- */
- CtsTime = ComputeTxTime(14, 10, 0, 0);
-
- /* Figure out time required to transmit this frame. */
- ThisFrameTime = ComputeTxTime(len + sCrcLng,
- rtl8180_rate2rate(rate), 0,
- bUseShortPreamble);
-
- /* RTS-CTS-ThisFrame-ACK. */
- RtsDur = CtsTime + ThisFrameTime +
- AckTime + 3 * aSifsTime;
-
- TxDescDuration = RtsTime + RtsDur;
- } else { /* Normal case. */
- bCTSEnable = 0;
- bRTSEnable = 0;
- RtsDur = 0;
-
- ThisFrameTime = ComputeTxTime(len + sCrcLng,
- rtl8180_rate2rate(rate), 0, bUseShortPreamble);
- TxDescDuration = ThisFrameTime + aSifsTime + AckTime;
- }
-
- if (!(le16_to_cpu(frag_hdr->frame_control) & IEEE80211_FCTL_MOREFRAGS)) {
- /* ThisFrame-ACK. */
- Duration = aSifsTime + AckTime;
- } else { /* One or more fragments remained. */
- u16 NextFragTime;
-
- /* pretend following packet length = current packet */
- NextFragTime = ComputeTxTime(len + sCrcLng,
- rtl8180_rate2rate(rate), 0, bUseShortPreamble);
-
- /* ThisFrag-ACk-NextFrag-ACK. */
- Duration = NextFragTime + 3 * aSifsTime + 2 * AckTime;
- }
-
- } /* End of Unicast packet */
-
- frag_hdr->duration_id = Duration;
-
- buflen = priv->txbuffsize;
- remain = len;
- temp_tail = tail;
-
- while (remain != 0) {
- mb();
- if (!buflist) {
- DMESGE("TX buffer error, cannot TX frames. pri %d.",
- priority);
- return -1;
- }
- buf = buflist->buf;
-
- if ((*tail & (1 << 31)) && (priority != BEACON_PRIORITY)) {
- DMESGW("No more TX desc, returning %x of %x",
- remain, len);
- priv->stats.txrdu++;
- return remain;
- }
-
- *tail = 0; /* zeroes header */
- *(tail+1) = 0;
- *(tail+3) = 0;
- *(tail+5) = 0;
- *(tail+6) = 0;
- *(tail+7) = 0;
-
- /* FIXME: should be triggered by HW encryption parameters.*/
- *tail |= (1<<15); /* no encrypt */
-
- if (remain == len && !descfrag) {
- ownbit_flag = false;
- *tail = *tail | (1 << 29); /* first segment of packet */
- *tail = *tail | (len);
- } else {
- ownbit_flag = true;
- }
-
- for (i = 0; i < buflen && remain > 0; i++, remain--) {
- /* copy data into descriptor pointed DMAble buffer */
- ((u8 *)buf)[i] = txbuf[i];
-
- if (remain == 4 && i+4 >= buflen)
- break;
- /* ensure the last desc has at least 4 bytes payload */
- }
- txbuf = txbuf + i;
- *(tail+3) = *(tail+3) & ~0xfff;
- *(tail+3) = *(tail+3) | i; /* buffer length */
-
- if (bCTSEnable)
- *tail |= (1<<18);
-
- if (bRTSEnable) { /* rts enable */
- /* RTS RATE */
- *tail |= (ieeerate2rtlrate(
- priv->ieee80211->basic_rate) << 19);
-
- *tail |= (1<<23); /* rts enable */
- *(tail+1) |= (RtsDur&0xffff); /* RTS Duration */
- }
- *(tail+3) |= ((TxDescDuration&0xffff)<<16); /* DURATION */
-
- *(tail + 5) |= (11 << 8); /* retry lim; */
-
- *tail = *tail | ((rate&0xf) << 24);
-
- if (morefrag)
- *tail = (*tail) | (1<<17); /* more fragment */
- if (!remain)
- *tail = (*tail) | (1<<28); /* last segment of frame */
-
- *(tail+5) = *(tail+5)|(2<<27);
- *(tail+7) = *(tail+7)|(1<<4);
-
- wmb();
- if (ownbit_flag)
- /* descriptor ready to be txed */
- *tail |= (1 << 31);
-
- if ((tail - begin)/8 == count-1)
- tail = begin;
- else
- tail = tail+8;
-
- buflist = buflist->next;
-
- mb();
-
- switch (priority) {
- case MANAGE_PRIORITY:
- priv->txmapringtail = tail;
- priv->txmapbufstail = buflist;
- break;
- case BK_PRIORITY:
- priv->txbkpringtail = tail;
- priv->txbkpbufstail = buflist;
- break;
- case BE_PRIORITY:
- priv->txbepringtail = tail;
- priv->txbepbufstail = buflist;
- break;
- case VI_PRIORITY:
- priv->txvipringtail = tail;
- priv->txvipbufstail = buflist;
- break;
- case VO_PRIORITY:
- priv->txvopringtail = tail;
- priv->txvopbufstail = buflist;
- break;
- case HI_PRIORITY:
- priv->txhpringtail = tail;
- priv->txhpbufstail = buflist;
- break;
- case BEACON_PRIORITY:
- /*
- * The HW seems to be happy with the 1st
- * descriptor filled and the 2nd empty...
- * So always update descriptor 1 and never
- * touch 2nd
- */
- break;
- }
- }
- *temp_tail = *temp_tail | (1<<31); /* descriptor ready to be txed */
- rtl8180_dma_kick(dev, priority);
-
- return 0;
-}
-
-void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
-
-static void rtl8180_link_change(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 beacon_interval;
- struct ieee80211_network *net = &priv->ieee80211->current_network;
-
- rtl8180_update_msr(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-
- write_nic_dword(dev, BSSID, ((u32 *)net->bssid)[0]);
- write_nic_word(dev, BSSID+4, ((u16 *)net->bssid)[2]);
-
- beacon_interval = read_nic_word(dev, BEACON_INTERVAL);
- beacon_interval &= ~BEACON_INTERVAL_MASK;
- beacon_interval |= net->beacon_interval;
- write_nic_word(dev, BEACON_INTERVAL, beacon_interval);
-
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
- rtl8180_set_chan(dev, priv->chan);
-}
-
-static void rtl8180_rq_tx_ack(struct net_device *dev)
-{
-
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- write_nic_byte(dev, CONFIG4,
- read_nic_byte(dev, CONFIG4) | CONFIG4_PWRMGT);
- priv->ack_tx_to_ieee = 1;
-}
-
-static short rtl8180_is_tx_queue_empty(struct net_device *dev)
-{
-
- struct r8180_priv *priv = ieee80211_priv(dev);
- u32 *d;
-
- for (d = priv->txmapring;
- d < priv->txmapring + priv->txringcount; d += 8)
- if (*d & (1<<31))
- return 0;
-
- for (d = priv->txbkpring;
- d < priv->txbkpring + priv->txringcount; d += 8)
- if (*d & (1<<31))
- return 0;
-
- for (d = priv->txbepring;
- d < priv->txbepring + priv->txringcount; d += 8)
- if (*d & (1<<31))
- return 0;
-
- for (d = priv->txvipring;
- d < priv->txvipring + priv->txringcount; d += 8)
- if (*d & (1<<31))
- return 0;
-
- for (d = priv->txvopring;
- d < priv->txvopring + priv->txringcount; d += 8)
- if (*d & (1<<31))
- return 0;
-
- for (d = priv->txhpring;
- d < priv->txhpring + priv->txringcount; d += 8)
- if (*d & (1<<31))
- return 0;
- return 1;
-}
-
-static void rtl8180_hw_wakeup(struct net_device *dev)
-{
- unsigned long flags;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- spin_lock_irqsave(&priv->ps_lock, flags);
- write_nic_byte(dev, CONFIG4,
- read_nic_byte(dev, CONFIG4) & ~CONFIG4_PWRMGT);
- if (priv->rf_wakeup)
- priv->rf_wakeup(dev);
- spin_unlock_irqrestore(&priv->ps_lock, flags);
-}
-
-static void rtl8180_hw_sleep_down(struct net_device *dev)
-{
- unsigned long flags;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- spin_lock_irqsave(&priv->ps_lock, flags);
- if (priv->rf_sleep)
- priv->rf_sleep(dev);
- spin_unlock_irqrestore(&priv->ps_lock, flags);
-}
-
-static void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u32 rb = jiffies;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->ps_lock, flags);
-
- /*
- * Writing HW register with 0 equals to disable
- * the timer, that is not really what we want
- */
- tl -= MSECS(4+16+7);
-
- /*
- * If the interval in which we are requested to sleep is too
- * short then give up and remain awake
- */
- if (((tl >= rb) && (tl-rb) <= MSECS(MIN_SLEEP_TIME))
- || ((rb > tl) && (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
- spin_unlock_irqrestore(&priv->ps_lock, flags);
- netdev_warn(dev, "too short to sleep\n");
- return;
- }
-
- {
- u32 tmp = (tl > rb) ? (tl-rb) : (rb-tl);
-
- priv->DozePeriodInPast2Sec += jiffies_to_msecs(tmp);
- /* as tl may be less than rb */
- queue_delayed_work(priv->ieee80211->wq,
- &priv->ieee80211->hw_wakeup_wq, tmp);
- }
- /*
- * If we suspect the TimerInt is gone beyond tl
- * while setting it, then give up
- */
-
- if (((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME))) ||
- ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
- spin_unlock_irqrestore(&priv->ps_lock, flags);
- return;
- }
-
- queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq);
- spin_unlock_irqrestore(&priv->ps_lock, flags);
-}
-
-static void rtl8180_wmm_single_param_update(struct net_device *dev,
- u8 mode, AC_CODING eACI, PAC_PARAM param)
-{
- u8 u1bAIFS;
- u32 u4bAcParam;
-
- /* Retrieve parameters to update. */
- /* Mode G/A: slotTimeTimer = 9; Mode B: 20 */
- u1bAIFS = param->f.AciAifsn.f.AIFSN * ((mode & IEEE_G) == IEEE_G ?
- 9 : 20) + aSifsTime;
- u4bAcParam = (((u32)param->f.TXOPLimit << AC_PARAM_TXOP_LIMIT_OFFSET) |
- ((u32)param->f.Ecw.f.ECWmax << AC_PARAM_ECW_MAX_OFFSET) |
- ((u32)param->f.Ecw.f.ECWmin << AC_PARAM_ECW_MIN_OFFSET) |
- ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
-
- switch (eACI) {
- case AC1_BK:
- write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
- return;
- case AC0_BE:
- write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
- return;
- case AC2_VI:
- write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
- return;
- case AC3_VO:
- write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
- return;
- default:
- pr_warn("SetHwReg8185(): invalid ACI: %d!\n", eACI);
- return;
- }
-}
-
-static void rtl8180_wmm_param_update(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(work,
- struct ieee80211_device, wmm_param_update_wq);
- struct net_device *dev = ieee->dev;
- u8 *ac_param = (u8 *)(ieee->current_network.wmm_param);
- u8 mode = ieee->current_network.mode;
- AC_CODING eACI;
- AC_PARAM AcParam;
-
- if (!ieee->current_network.QoS_Enable) {
- /* legacy ac_xx_param update */
- AcParam.longData = 0;
- AcParam.f.AciAifsn.f.AIFSN = 2; /* Follow 802.11 DIFS. */
- AcParam.f.AciAifsn.f.ACM = 0;
- AcParam.f.Ecw.f.ECWmin = 3; /* Follow 802.11 CWmin. */
- AcParam.f.Ecw.f.ECWmax = 7; /* Follow 802.11 CWmax. */
- AcParam.f.TXOPLimit = 0;
-
- for (eACI = 0; eACI < AC_MAX; eACI++) {
- AcParam.f.AciAifsn.f.ACI = (u8)eACI;
-
- rtl8180_wmm_single_param_update(dev, mode, eACI,
- (PAC_PARAM)&AcParam);
- }
- return;
- }
-
- for (eACI = 0; eACI < AC_MAX; eACI++) {
- rtl8180_wmm_single_param_update(dev, mode,
- ((PAC_PARAM)ac_param)->f.AciAifsn.f.ACI,
- (PAC_PARAM)ac_param);
-
- ac_param += sizeof(AC_PARAM);
- }
-}
-
-void rtl8180_restart_wq(struct work_struct *work);
-void rtl8180_watch_dog_wq(struct work_struct *work);
-void rtl8180_hw_wakeup_wq(struct work_struct *work);
-void rtl8180_hw_sleep_wq(struct work_struct *work);
-void rtl8180_sw_antenna_wq(struct work_struct *work);
-void rtl8180_watch_dog(struct net_device *dev);
-
-static void watch_dog_adaptive(unsigned long data)
-{
- struct r8180_priv *priv = ieee80211_priv((struct net_device *)data);
-
- if (!priv->up) {
- DMESG("<----watch_dog_adaptive():driver is not up!\n");
- return;
- }
-
- /* Tx High Power Mechanism. */
- if (CheckHighPower((struct net_device *)data))
- queue_work(priv->ieee80211->wq,
- (void *)&priv->ieee80211->tx_pw_wq);
-
- /* Tx Power Tracking on 87SE. */
- if (CheckTxPwrTracking((struct net_device *)data))
- TxPwrTracking87SE((struct net_device *)data);
-
- /* Perform DIG immediately. */
- if (CheckDig((struct net_device *)data))
- queue_work(priv->ieee80211->wq,
- (void *)&priv->ieee80211->hw_dig_wq);
-
- rtl8180_watch_dog((struct net_device *)data);
-
- queue_work(priv->ieee80211->wq,
- (void *)&priv->ieee80211->GPIOChangeRFWorkItem);
-
- priv->watch_dog_timer.expires = jiffies +
- MSECS(IEEE80211_WATCH_DOG_TIME);
-
- add_timer(&priv->watch_dog_timer);
-}
-
-static struct rtl8187se_channel_list channel_plan_list[] = {
- /* FCC */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40,
- 44, 48, 52, 56, 60, 64}, 19},
-
- /* IC */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
-
- /* ETSI */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40,
- 44, 48, 52, 56, 60, 64}, 21},
-
- /* Spain. Change to ETSI. */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40,
- 44, 48, 52, 56, 60, 64}, 21},
-
- /* France. Change to ETSI. */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40,
- 44, 48, 52, 56, 60, 64}, 21},
-
- /* MKK */
- {{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9},
-
- /* MKK1 */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36,
- 40, 44, 48, 52, 56, 60, 64}, 22},
-
- /* Israel. */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40,
- 44, 48, 52, 56, 60, 64}, 21},
-
- /* For 11a , TELEC */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17},
-
- /* For Global Domain. 1-11 active, 12-14 passive. */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
-
- /* world wide 13: ch1~ch11 active, ch12~13 passive */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}
-};
-
-static void rtl8180_set_channel_map(u8 channel_plan,
- struct ieee80211_device *ieee)
-{
- int i;
-
- ieee->MinPassiveChnlNum = MAX_CHANNEL_NUMBER+1;
- ieee->IbssStartChnl = 0;
-
- switch (channel_plan) {
- case COUNTRY_CODE_FCC:
- case COUNTRY_CODE_IC:
- case COUNTRY_CODE_ETSI:
- case COUNTRY_CODE_SPAIN:
- case COUNTRY_CODE_FRANCE:
- case COUNTRY_CODE_MKK:
- case COUNTRY_CODE_MKK1:
- case COUNTRY_CODE_ISRAEL:
- case COUNTRY_CODE_TELEC:
- {
- Dot11d_Init(ieee);
- ieee->bGlobalDomain = false;
- if (channel_plan_list[channel_plan].len != 0) {
- /* Clear old channel map */
- memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
- /* Set new channel map */
- for (i = 0; i < channel_plan_list[channel_plan].len; i++) {
- if (channel_plan_list[channel_plan].channel[i] <= 14)
- GET_DOT11D_INFO(ieee)->channel_map[channel_plan_list[channel_plan].channel[i]] = 1;
- }
- }
- break;
- }
- case COUNTRY_CODE_GLOBAL_DOMAIN:
- {
- GET_DOT11D_INFO(ieee)->bEnabled = false;
- Dot11d_Reset(ieee);
- ieee->bGlobalDomain = true;
- break;
- }
- case COUNTRY_CODE_WORLD_WIDE_13_INDEX:
- {
- ieee->MinPassiveChnlNum = 12;
- ieee->IbssStartChnl = 10;
- break;
- }
- default:
- {
- Dot11d_Init(ieee);
- ieee->bGlobalDomain = false;
- memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
- for (i = 1; i <= 14; i++)
- GET_DOT11D_INFO(ieee)->channel_map[i] = 1;
- break;
- }
- }
-}
-
-void GPIOChangeRFWorkItemCallBack(struct work_struct *work);
-
-static void rtl8180_statistics_init(struct stats *pstats)
-{
- memset(pstats, 0, sizeof(struct stats));
-}
-
-static void rtl8180_link_detect_init(struct link_detect_t *plink_detect)
-{
- memset(plink_detect, 0, sizeof(struct link_detect_t));
- plink_detect->slot_num = DEFAULT_SLOT_NUM;
-}
-
-static void rtl8187se_eeprom_register_read(struct eeprom_93cx6 *eeprom)
-{
- struct net_device *dev = eeprom->data;
- u8 reg = read_nic_byte(dev, EPROM_CMD);
-
- eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
- eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
- eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
- eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
-}
-
-static void rtl8187se_eeprom_register_write(struct eeprom_93cx6 *eeprom)
-{
- struct net_device *dev = eeprom->data;
- u8 reg = 2 << 6;
-
- if (eeprom->reg_data_in)
- reg |= RTL818X_EEPROM_CMD_WRITE;
- if (eeprom->reg_data_out)
- reg |= RTL818X_EEPROM_CMD_READ;
- if (eeprom->reg_data_clock)
- reg |= RTL818X_EEPROM_CMD_CK;
- if (eeprom->reg_chip_select)
- reg |= RTL818X_EEPROM_CMD_CS;
-
- write_nic_byte(dev, EPROM_CMD, reg);
- read_nic_byte(dev, EPROM_CMD);
- udelay(10);
-}
-
-static short rtl8180_init(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 word;
- u16 usValue;
- u16 tmpu16;
- int i, j;
- struct eeprom_93cx6 eeprom;
- u16 eeprom_val;
-
- eeprom.data = dev;
- eeprom.register_read = rtl8187se_eeprom_register_read;
- eeprom.register_write = rtl8187se_eeprom_register_write;
- eeprom.width = PCI_EEPROM_WIDTH_93C46;
-
- eeprom_93cx6_read(&eeprom, EEPROM_COUNTRY_CODE>>1, &eeprom_val);
- priv->channel_plan = eeprom_val & 0xFF;
- if (priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN) {
- netdev_err(dev, "rtl8180_init: Invalid channel plan! Set to default.\n");
- priv->channel_plan = 0;
- }
-
- DMESG("Channel plan is %d\n", priv->channel_plan);
- rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211);
-
- /* FIXME: these constants are placed in a bad pleace. */
- priv->txbuffsize = 2048; /* 1024; */
- priv->txringcount = 32; /* 32; */
- priv->rxbuffersize = 2048; /* 1024; */
- priv->rxringcount = 64; /* 32; */
- priv->txbeaconcount = 2;
- priv->rx_skb_complete = 1;
-
- priv->RFChangeInProgress = false;
- priv->SetRFPowerStateInProgress = false;
- priv->RFProgType = 0;
-
- priv->irq_enabled = 0;
-
- rtl8180_statistics_init(&priv->stats);
- rtl8180_link_detect_init(&priv->link_detect);
-
- priv->ack_tx_to_ieee = 0;
- priv->ieee80211->current_network.beacon_interval =
- DEFAULT_BEACONINTERVAL;
- priv->ieee80211->iw_mode = IW_MODE_INFRA;
- priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
- IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
- IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;
- priv->ieee80211->active_scan = 1;
- priv->ieee80211->rate = 110; /* 11 mbps */
- priv->ieee80211->modulation = IEEE80211_CCK_MODULATION;
- priv->ieee80211->host_encrypt = 1;
- priv->ieee80211->host_decrypt = 1;
- priv->ieee80211->sta_wake_up = rtl8180_hw_wakeup;
- priv->ieee80211->ps_request_tx_ack = rtl8180_rq_tx_ack;
- priv->ieee80211->enter_sleep_state = rtl8180_hw_sleep;
- priv->ieee80211->ps_is_queue_empty = rtl8180_is_tx_queue_empty;
-
- priv->hw_wep = hwwep;
- priv->dev = dev;
- priv->retry_rts = DEFAULT_RETRY_RTS;
- priv->retry_data = DEFAULT_RETRY_DATA;
- priv->RFChangeInProgress = false;
- priv->SetRFPowerStateInProgress = false;
- priv->RFProgType = 0;
- priv->bInactivePs = true; /* false; */
- priv->ieee80211->bInactivePs = priv->bInactivePs;
- priv->bSwRfProcessing = false;
- priv->eRFPowerState = RF_OFF;
- priv->RfOffReason = 0;
- priv->led_strategy = SW_LED_MODE0;
- priv->TxPollingTimes = 0;
- priv->bLeisurePs = true;
- priv->dot11PowerSaveMode = ACTIVE;
- priv->AdMinCheckPeriod = 5;
- priv->AdMaxCheckPeriod = 10;
- priv->AdMaxRxSsThreshold = 30; /* 60->30 */
- priv->AdRxSsThreshold = 20; /* 50->20 */
- priv->AdCheckPeriod = priv->AdMinCheckPeriod;
- priv->AdTickCount = 0;
- priv->AdRxSignalStrength = -1;
- priv->RegSwAntennaDiversityMechanism = 0;
- priv->RegDefaultAntenna = 0;
- priv->SignalStrength = 0;
- priv->AdRxOkCnt = 0;
- priv->CurrAntennaIndex = 0;
- priv->AdRxSsBeforeSwitched = 0;
- init_timer(&priv->SwAntennaDiversityTimer);
- priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
- priv->SwAntennaDiversityTimer.function =
- (void *)SwAntennaDiversityTimerCallback;
- priv->bDigMechanism = true;
- priv->InitialGain = 6;
- priv->bXtalCalibration = false;
- priv->XtalCal_Xin = 0;
- priv->XtalCal_Xout = 0;
- priv->bTxPowerTrack = false;
- priv->ThermalMeter = 0;
- priv->FalseAlarmRegValue = 0;
- priv->RegDigOfdmFaUpTh = 0xc; /* Upper threshold of OFDM false alarm,
- which is used in DIG. */
- priv->DIG_NumberFallbackVote = 0;
- priv->DIG_NumberUpgradeVote = 0;
- priv->LastSignalStrengthInPercent = 0;
- priv->Stats_SignalStrength = 0;
- priv->LastRxPktAntenna = 0;
- priv->SignalQuality = 0; /* in 0-100 index. */
- priv->Stats_SignalQuality = 0;
- priv->RecvSignalPower = 0; /* in dBm. */
- priv->Stats_RecvSignalPower = 0;
- priv->AdMainAntennaRxOkCnt = 0;
- priv->AdAuxAntennaRxOkCnt = 0;
- priv->bHWAdSwitched = false;
- priv->bRegHighPowerMechanism = true;
- priv->RegHiPwrUpperTh = 77;
- priv->RegHiPwrLowerTh = 75;
- priv->RegRSSIHiPwrUpperTh = 70;
- priv->RegRSSIHiPwrLowerTh = 20;
- priv->bCurCCKPkt = false;
- priv->UndecoratedSmoothedSS = -1;
- priv->bToUpdateTxPwr = false;
- priv->CurCCKRSSI = 0;
- priv->RxPower = 0;
- priv->RSSI = 0;
- priv->NumTxOkTotal = 0;
- priv->NumTxUnicast = 0;
- priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL;
- priv->CurrRetryCnt = 0;
- priv->LastRetryCnt = 0;
- priv->LastTxokCnt = 0;
- priv->LastRxokCnt = 0;
- priv->LastRetryRate = 0;
- priv->bTryuping = 0;
- priv->CurrTxRate = 0;
- priv->CurrRetryRate = 0;
- priv->TryupingCount = 0;
- priv->TryupingCountNoData = 0;
- priv->TryDownCountLowData = 0;
- priv->LastTxOKBytes = 0;
- priv->LastFailTxRate = 0;
- priv->LastFailTxRateSS = 0;
- priv->FailTxRateCount = 0;
- priv->LastTxThroughput = 0;
- priv->NumTxOkBytesTotal = 0;
- priv->ForcedDataRate = 0;
- priv->RegBModeGainStage = 1;
-
- priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
- spin_lock_init(&priv->irq_th_lock);
- spin_lock_init(&priv->tx_lock);
- spin_lock_init(&priv->ps_lock);
- spin_lock_init(&priv->rf_ps_lock);
- sema_init(&priv->wx_sem, 1);
- INIT_WORK(&priv->reset_wq, (void *)rtl8180_restart_wq);
- INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,
- (void *)rtl8180_hw_wakeup_wq);
- INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,
- (void *)rtl8180_hw_sleep_wq);
- INIT_WORK(&priv->ieee80211->wmm_param_update_wq,
- (void *)rtl8180_wmm_param_update);
- INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,
- (void *)rtl8180_rate_adapter);
- INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,
- (void *)rtl8180_hw_dig_wq);
- INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,
- (void *)rtl8180_tx_pw_wq);
- INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,
- (void *) GPIOChangeRFWorkItemCallBack);
- tasklet_init(&priv->irq_rx_tasklet,
- (void(*)(unsigned long)) rtl8180_irq_rx_tasklet,
- (unsigned long)priv);
-
- init_timer(&priv->watch_dog_timer);
- priv->watch_dog_timer.data = (unsigned long)dev;
- priv->watch_dog_timer.function = watch_dog_adaptive;
-
- init_timer(&priv->rateadapter_timer);
- priv->rateadapter_timer.data = (unsigned long)dev;
- priv->rateadapter_timer.function = timer_rate_adaptive;
- priv->RateAdaptivePeriod = RATE_ADAPTIVE_TIMER_PERIOD;
- priv->bEnhanceTxPwr = false;
-
- priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
- priv->ieee80211->set_chan = rtl8180_set_chan;
- priv->ieee80211->link_change = rtl8180_link_change;
- priv->ieee80211->softmac_data_hard_start_xmit = rtl8180_hard_data_xmit;
- priv->ieee80211->data_hard_stop = rtl8180_data_hard_stop;
- priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume;
-
- priv->ieee80211->init_wmmparam_flag = 0;
-
- priv->ieee80211->start_send_beacons = rtl8180_start_tx_beacon;
- priv->ieee80211->stop_send_beacons = rtl8180_beacon_tx_disable;
- priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
-
- priv->ShortRetryLimit = 7;
- priv->LongRetryLimit = 7;
- priv->EarlyRxThreshold = 7;
-
- priv->TransmitConfig = (1<<TCR_DurProcMode_OFFSET) |
- (7<<TCR_MXDMA_OFFSET) |
- (priv->ShortRetryLimit<<TCR_SRL_OFFSET) |
- (priv->LongRetryLimit<<TCR_LRL_OFFSET);
-
- priv->ReceiveConfig = RCR_AMF | RCR_ADF | RCR_ACF |
- RCR_AB | RCR_AM | RCR_APM |
- (7<<RCR_MXDMA_OFFSET) |
- (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) |
- (priv->EarlyRxThreshold == 7 ?
- RCR_ONLYERLPKT : 0);
-
- priv->IntrMask = IMR_TMGDOK | IMR_TBDER |
- IMR_THPDER | IMR_THPDOK |
- IMR_TVODER | IMR_TVODOK |
- IMR_TVIDER | IMR_TVIDOK |
- IMR_TBEDER | IMR_TBEDOK |
- IMR_TBKDER | IMR_TBKDOK |
- IMR_RDU |
- IMR_RER | IMR_ROK |
- IMR_RQoSOK;
-
- priv->InitialGain = 6;
-
- DMESG("MAC controller is a RTL8187SE b/g");
-
- priv->ieee80211->modulation |= IEEE80211_OFDM_MODULATION;
- priv->ieee80211->short_slot = 1;
-
- eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &usValue);
- DMESG("usValue is %#hx\n", usValue);
- /* 3Read AntennaDiversity */
-
- /* SW Antenna Diversity. */
- priv->EEPROMSwAntennaDiversity = (usValue & EEPROM_SW_AD_MASK) ==
- EEPROM_SW_AD_ENABLE;
-
- /* Default Antenna to use. */
- priv->EEPROMDefaultAntenna1 = (usValue & EEPROM_DEF_ANT_MASK) ==
- EEPROM_DEF_ANT_1;
-
- if (priv->RegSwAntennaDiversityMechanism == 0) /* Auto */
- /* 0: default from EEPROM. */
- priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity;
- else
- /* 1:disable antenna diversity, 2: enable antenna diversity. */
- priv->bSwAntennaDiverity =
- priv->RegSwAntennaDiversityMechanism == 2;
-
- if (priv->RegDefaultAntenna == 0)
- /* 0: default from EEPROM. */
- priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1;
- else
- /* 1: main, 2: aux. */
- priv->bDefaultAntenna1 = priv->RegDefaultAntenna == 2;
-
- priv->plcp_preamble_mode = 2;
- /* the eeprom type is stored in RCR register bit #6 */
- if (RCR_9356SEL & read_nic_dword(dev, RCR))
- priv->epromtype = EPROM_93c56;
- else
- priv->epromtype = EPROM_93c46;
-
- eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)
- dev->dev_addr, 3);
-
- for (i = 1, j = 0; i < 14; i += 2, j++) {
- eeprom_93cx6_read(&eeprom, EPROM_TXPW_CH1_2 + j, &word);
- priv->chtxpwr[i] = word & 0xff;
- priv->chtxpwr[i+1] = (word & 0xff00)>>8;
- }
- for (i = 1, j = 0; i < 14; i += 2, j++) {
- eeprom_93cx6_read(&eeprom, EPROM_TXPW_OFDM_CH1_2 + j, &word);
- priv->chtxpwr_ofdm[i] = word & 0xff;
- priv->chtxpwr_ofdm[i+1] = (word & 0xff00) >> 8;
- }
-
- /* 3Read crystal calibration and thermal meter indication on 87SE. */
- eeprom_93cx6_read(&eeprom, EEPROM_RSV>>1, &tmpu16);
-
- /* Crystal calibration for Xin and Xout resp. */
- priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK;
- priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK) >> 4;
- if ((tmpu16 & EEPROM_XTAL_CAL_ENABLE) >> 12)
- priv->bXtalCalibration = true;
-
- /* Thermal meter reference indication. */
- priv->ThermalMeter = (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK) >> 8);
- if ((tmpu16 & EEPROM_THERMAL_METER_ENABLE) >> 13)
- priv->bTxPowerTrack = true;
-
- priv->rf_sleep = rtl8225z4_rf_sleep;
- priv->rf_wakeup = rtl8225z4_rf_wakeup;
- DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!");
-
- priv->rf_close = rtl8225z2_rf_close;
- priv->rf_init = rtl8225z2_rf_init;
- priv->rf_set_chan = rtl8225z2_rf_set_chan;
- priv->rf_set_sens = NULL;
-
- if (0 != alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
- TX_MANAGEPRIORITY_RING_ADDR))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
- TX_BKPRIORITY_RING_ADDR))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
- TX_BEPRIORITY_RING_ADDR))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
- TX_VIPRIORITY_RING_ADDR))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
- TX_VOPRIORITY_RING_ADDR))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
- TX_HIGHPRIORITY_RING_ADDR))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txbeaconcount,
- TX_BEACON_RING_ADDR))
- return -ENOMEM;
-
- if (request_irq(dev->irq, rtl8180_interrupt,
- IRQF_SHARED, dev->name, dev)) {
- DMESGE("Error allocating IRQ %d", dev->irq);
- return -1;
- } else {
- priv->irq = dev->irq;
- DMESG("IRQ %d", dev->irq);
- }
-
- return 0;
-}
-
-void rtl8180_no_hw_wep(struct net_device *dev)
-{
-}
-
-void rtl8180_set_hw_wep(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 pgreg;
- u8 security;
- u32 key0_word4;
-
- pgreg = read_nic_byte(dev, PGSELECT);
- write_nic_byte(dev, PGSELECT, pgreg & ~(1<<PGSELECT_PG_SHIFT));
-
- key0_word4 = read_nic_dword(dev, KEY0+4+4+4);
- key0_word4 &= ~0xff;
- key0_word4 |= priv->key0[3] & 0xff;
- write_nic_dword(dev, KEY0, (priv->key0[0]));
- write_nic_dword(dev, KEY0+4, (priv->key0[1]));
- write_nic_dword(dev, KEY0+4+4, (priv->key0[2]));
- write_nic_dword(dev, KEY0+4+4+4, (key0_word4));
-
- security = read_nic_byte(dev, SECURITY);
- security |= (1<<SECURITY_WEP_TX_ENABLE_SHIFT);
- security |= (1<<SECURITY_WEP_RX_ENABLE_SHIFT);
- security &= ~SECURITY_ENCRYP_MASK;
- security |= (SECURITY_ENCRYP_104<<SECURITY_ENCRYP_SHIFT);
-
- write_nic_byte(dev, SECURITY, security);
-
- DMESG("key %x %x %x %x", read_nic_dword(dev, KEY0+4+4+4),
- read_nic_dword(dev, KEY0+4+4), read_nic_dword(dev, KEY0+4),
- read_nic_dword(dev, KEY0));
-}
-
-
-void rtl8185_rf_pins_enable(struct net_device *dev)
-{
- write_nic_word(dev, RFPinsEnable, 0x1fff); /* | tmp); */
-}
-
-void rtl8185_set_anaparam2(struct net_device *dev, u32 a)
-{
- u8 conf3;
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-
- conf3 = read_nic_byte(dev, CONFIG3);
- write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
- write_nic_dword(dev, ANAPARAM2, a);
-
- conf3 = read_nic_byte(dev, CONFIG3);
- write_nic_byte(dev, CONFIG3, conf3 & ~(1<<CONFIG3_ANAPARAM_W_SHIFT));
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-void rtl8180_set_anaparam(struct net_device *dev, u32 a)
-{
- u8 conf3;
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-
- conf3 = read_nic_byte(dev, CONFIG3);
- write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
- write_nic_dword(dev, ANAPARAM, a);
-
- conf3 = read_nic_byte(dev, CONFIG3);
- write_nic_byte(dev, CONFIG3, conf3 & ~(1<<CONFIG3_ANAPARAM_W_SHIFT));
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
-{
- write_nic_byte(dev, TX_ANTENNA, ant);
- force_pci_posting(dev);
- mdelay(1);
-}
-
-static void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data)
-{
- u32 phyw;
-
- adr |= 0x80;
-
- phyw = ((data<<8) | adr);
-
- /* Note: we must write 0xff7c after 0x7d-0x7f to write BB register. */
- write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
- write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
- write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
- write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff)));
-}
-
-inline void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data)
-{
- data = data & 0xff;
- rtl8185_write_phy(dev, adr, data);
-}
-
-void write_phy_cck(struct net_device *dev, u8 adr, u32 data)
-{
- data = data & 0xff;
- rtl8185_write_phy(dev, adr, data | 0x10000);
-}
-
-/*
- * This configures registers for beacon tx and enables it via
- * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might
- * be used to stop beacon transmission
- */
-void rtl8180_start_tx_beacon(struct net_device *dev)
-{
- u16 word;
-
- DMESG("Enabling beacon TX");
- rtl8180_prepare_beacon(dev);
- rtl8180_irq_disable(dev);
- rtl8180_beacon_tx_enable(dev);
-
- word = read_nic_word(dev, AtimWnd) & ~AtimWnd_AtimWnd;
- write_nic_word(dev, AtimWnd, word); /* word |= */
-
- word = read_nic_word(dev, BintrItv);
- word &= ~BintrItv_BintrItv;
- word |= 1000; /* priv->ieee80211->current_network.beacon_interval *
- * ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
- * FIXME: check if correct ^^ worked with 0x3e8;
- */
- write_nic_word(dev, BintrItv, word);
-
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
- rtl8185b_irq_enable(dev);
-}
-
-static struct net_device_stats *rtl8180_stats(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- return &priv->ieee80211->stats;
-}
-
-/*
- * Change current and default preamble mode.
- */
-static bool MgntActSet_802_11_PowerSaveMode(struct r8180_priv *priv,
- enum rt_ps_mode rtPsMode)
-{
- /* Currently, we do not change power save mode on IBSS mode. */
- if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- return false;
-
- priv->ieee80211->ps = rtPsMode;
-
- return true;
-}
-
-static void LeisurePSEnter(struct r8180_priv *priv)
-{
- if (priv->bLeisurePs)
- if (priv->ieee80211->ps == IEEE80211_PS_DISABLED)
- /* IEEE80211_PS_ENABLE */
- MgntActSet_802_11_PowerSaveMode(priv,
- IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST);
-}
-
-static void LeisurePSLeave(struct r8180_priv *priv)
-{
- if (priv->bLeisurePs)
- if (priv->ieee80211->ps != IEEE80211_PS_DISABLED)
- MgntActSet_802_11_PowerSaveMode(
- priv, IEEE80211_PS_DISABLED);
-}
-
-void rtl8180_hw_wakeup_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(
- dwork, struct ieee80211_device, hw_wakeup_wq);
- struct net_device *dev = ieee->dev;
-
- rtl8180_hw_wakeup(dev);
-}
-
-void rtl8180_hw_sleep_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(
- dwork, struct ieee80211_device, hw_sleep_wq);
- struct net_device *dev = ieee->dev;
-
- rtl8180_hw_sleep_down(dev);
-}
-
-static void MgntLinkKeepAlive(struct r8180_priv *priv)
-{
- if (priv->keepAliveLevel == 0)
- return;
-
- if (priv->ieee80211->state == IEEE80211_LINKED) {
- /*
- * Keep-Alive.
- */
-
- if ((priv->keepAliveLevel == 2) ||
- (priv->link_detect.last_num_tx_unicast ==
- priv->NumTxUnicast &&
- priv->link_detect.last_num_rx_unicast ==
- priv->ieee80211->NumRxUnicast)
- ) {
- priv->link_detect.idle_count++;
-
- /*
- * Send a Keep-Alive packet packet to AP if we had
- * been idle for a while.
- */
- if (priv->link_detect.idle_count >=
- KEEP_ALIVE_INTERVAL /
- CHECK_FOR_HANG_PERIOD - 1) {
- priv->link_detect.idle_count = 0;
- ieee80211_sta_ps_send_null_frame(
- priv->ieee80211, false);
- }
- } else {
- priv->link_detect.idle_count = 0;
- }
- priv->link_detect.last_num_tx_unicast = priv->NumTxUnicast;
- priv->link_detect.last_num_rx_unicast =
- priv->ieee80211->NumRxUnicast;
- }
-}
-
-void rtl8180_watch_dog(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- bool bEnterPS = false;
- bool bBusyTraffic = false;
- u32 TotalRxNum = 0;
- u16 SlotIndex = 0;
- u16 i = 0;
- if (priv->ieee80211->actscanning == false) {
- if ((priv->ieee80211->iw_mode != IW_MODE_ADHOC) &&
- (priv->ieee80211->state == IEEE80211_NOLINK) &&
- (priv->ieee80211->beinretry == false) &&
- (priv->eRFPowerState == RF_ON))
- IPSEnter(dev);
- }
- if ((priv->ieee80211->state == IEEE80211_LINKED) &&
- (priv->ieee80211->iw_mode == IW_MODE_INFRA)) {
- SlotIndex = (priv->link_detect.slot_index++) %
- priv->link_detect.slot_num;
-
- priv->link_detect.rx_frame_num[SlotIndex] =
- priv->ieee80211->NumRxDataInPeriod +
- priv->ieee80211->NumRxBcnInPeriod;
-
- for (i = 0; i < priv->link_detect.slot_num; i++)
- TotalRxNum += priv->link_detect.rx_frame_num[i];
-
- if (TotalRxNum == 0) {
- priv->ieee80211->state = IEEE80211_ASSOCIATING;
- queue_work(priv->ieee80211->wq,
- &priv->ieee80211->associate_procedure_wq);
- }
- }
-
- MgntLinkKeepAlive(priv);
-
- LeisurePSLeave(priv);
-
- if (priv->ieee80211->state == IEEE80211_LINKED) {
- priv->link_detect.num_rx_ok_in_period =
- priv->ieee80211->NumRxDataInPeriod;
- if (priv->link_detect.num_rx_ok_in_period > 666 ||
- priv->link_detect.num_tx_ok_in_period > 666) {
- bBusyTraffic = true;
- }
- if ((priv->link_detect.num_rx_ok_in_period +
- priv->link_detect.num_tx_ok_in_period > 8)
- || (priv->link_detect.num_rx_ok_in_period > 2)) {
- bEnterPS = false;
- } else
- bEnterPS = true;
-
- if (bEnterPS)
- LeisurePSEnter(priv);
- else
- LeisurePSLeave(priv);
- } else
- LeisurePSLeave(priv);
- priv->link_detect.b_busy_traffic = bBusyTraffic;
- priv->link_detect.num_rx_ok_in_period = 0;
- priv->link_detect.num_tx_ok_in_period = 0;
- priv->ieee80211->NumRxDataInPeriod = 0;
- priv->ieee80211->NumRxBcnInPeriod = 0;
-}
-
-static int _rtl8180_up(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- priv->up = 1;
-
- DMESG("Bringing up iface");
- rtl8185b_adapter_start(dev);
- rtl8185b_rx_enable(dev);
- rtl8185b_tx_enable(dev);
- if (priv->bInactivePs) {
- if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- IPSLeave(dev);
- }
- timer_rate_adaptive((unsigned long)dev);
- watch_dog_adaptive((unsigned long)dev);
- if (priv->bSwAntennaDiverity)
- SwAntennaDiversityTimerCallback(dev);
- ieee80211_softmac_start_protocol(priv->ieee80211);
- return 0;
-}
-
-static int rtl8180_open(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret;
-
- down(&priv->wx_sem);
- ret = rtl8180_up(dev);
- up(&priv->wx_sem);
- return ret;
-}
-
-int rtl8180_up(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->up == 1)
- return -1;
-
- return _rtl8180_up(dev);
-}
-
-static int rtl8180_close(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret;
-
- down(&priv->wx_sem);
- ret = rtl8180_down(dev);
- up(&priv->wx_sem);
-
- return ret;
-}
-
-int rtl8180_down(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->up == 0)
- return -1;
-
- priv->up = 0;
-
- ieee80211_softmac_stop_protocol(priv->ieee80211);
- /* FIXME */
- if (!netif_queue_stopped(dev))
- netif_stop_queue(dev);
- rtl8180_rtx_disable(dev);
- rtl8180_irq_disable(dev);
- del_timer_sync(&priv->watch_dog_timer);
- del_timer_sync(&priv->rateadapter_timer);
- cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
- cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
- cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
- cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
- cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
- del_timer_sync(&priv->SwAntennaDiversityTimer);
- SetZebraRFPowerState8185(dev, RF_OFF);
- memset(&priv->ieee80211->current_network,
- 0, sizeof(struct ieee80211_network));
- priv->ieee80211->state = IEEE80211_NOLINK;
- return 0;
-}
-
-void rtl8180_restart_wq(struct work_struct *work)
-{
- struct r8180_priv *priv = container_of(
- work, struct r8180_priv, reset_wq);
- struct net_device *dev = priv->dev;
-
- down(&priv->wx_sem);
-
- rtl8180_commit(dev);
-
- up(&priv->wx_sem);
-}
-
-static void rtl8180_restart(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- schedule_work(&priv->reset_wq);
-}
-
-void rtl8180_commit(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->up == 0)
- return;
-
- del_timer_sync(&priv->watch_dog_timer);
- del_timer_sync(&priv->rateadapter_timer);
- cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
- cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
- cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
- cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
- cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
- del_timer_sync(&priv->SwAntennaDiversityTimer);
- ieee80211_softmac_stop_protocol(priv->ieee80211);
- rtl8180_irq_disable(dev);
- rtl8180_rtx_disable(dev);
- _rtl8180_up(dev);
-}
-
-static void r8180_set_multicast(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- short promisc;
-
- promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
-
- if (promisc != priv->promisc)
- rtl8180_restart(dev);
-
- priv->promisc = promisc;
-}
-
-static int r8180_set_mac_adr(struct net_device *dev, void *mac)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct sockaddr *addr = mac;
-
- down(&priv->wx_sem);
-
- memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
-
- if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
- memcpy(priv->ieee80211->current_network.bssid,
- dev->dev_addr, ETH_ALEN);
-
- if (priv->up) {
- rtl8180_down(dev);
- rtl8180_up(dev);
- }
-
- up(&priv->wx_sem);
-
- return 0;
-}
-
-/* based on ipw2200 driver */
-static int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct iwreq *wrq = (struct iwreq *) rq;
- int ret = -1;
-
- switch (cmd) {
- case RTL_IOCTL_WPA_SUPPLICANT:
- ret = ieee80211_wpa_supplicant_ioctl(
- priv->ieee80211, &wrq->u.data);
- return ret;
- default:
- return -EOPNOTSUPP;
- }
-
- return -EOPNOTSUPP;
-}
-
-static const struct net_device_ops rtl8180_netdev_ops = {
- .ndo_open = rtl8180_open,
- .ndo_stop = rtl8180_close,
- .ndo_get_stats = rtl8180_stats,
- .ndo_tx_timeout = rtl8180_restart,
- .ndo_do_ioctl = rtl8180_ioctl,
- .ndo_set_rx_mode = r8180_set_multicast,
- .ndo_set_mac_address = r8180_set_mac_adr,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_start_xmit = ieee80211_rtl_xmit,
-};
-
-static int rtl8180_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- unsigned long ioaddr = 0;
- struct net_device *dev = NULL;
- struct r8180_priv *priv = NULL;
- u8 unit = 0;
- int ret = -ENODEV;
-
- unsigned long pmem_start, pmem_len, pmem_flags;
-
- DMESG("Configuring chip resources");
-
- if (pci_enable_device(pdev)) {
- DMESG("Failed to enable PCI device");
- return -EIO;
- }
-
- pci_set_master(pdev);
- pci_set_dma_mask(pdev, 0xffffff00ULL);
- pci_set_consistent_dma_mask(pdev, 0xffffff00ULL);
- dev = alloc_ieee80211(sizeof(struct r8180_priv));
- if (!dev) {
- ret = -ENOMEM;
- goto fail_free;
- }
- priv = ieee80211_priv(dev);
- priv->ieee80211 = netdev_priv(dev);
-
- pci_set_drvdata(pdev, dev);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- priv = ieee80211_priv(dev);
- priv->pdev = pdev;
-
- pmem_start = pci_resource_start(pdev, 1);
- pmem_len = pci_resource_len(pdev, 1);
- pmem_flags = pci_resource_flags(pdev, 1);
-
- if (!(pmem_flags & IORESOURCE_MEM)) {
- DMESG("region #1 not a MMIO resource, aborting");
- goto fail;
- }
-
- if (!request_mem_region(pmem_start, pmem_len, RTL8180_MODULE_NAME)) {
- DMESG("request_mem_region failed!");
- goto fail;
- }
-
- ioaddr = (unsigned long)ioremap_nocache(pmem_start, pmem_len);
- if (ioaddr == (unsigned long)NULL) {
- DMESG("ioremap failed!");
- goto fail1;
- }
-
- dev->mem_start = ioaddr; /* shared mem start */
- dev->mem_end = ioaddr + pci_resource_len(pdev, 0); /* shared mem end */
-
- pci_read_config_byte(pdev, 0x05, &unit);
- pci_write_config_byte(pdev, 0x05, unit & (~0x04));
-
- dev->irq = pdev->irq;
- priv->irq = 0;
-
- dev->netdev_ops = &rtl8180_netdev_ops;
- dev->wireless_handlers = &r8180_wx_handlers_def;
-
- dev->type = ARPHRD_ETHER;
- dev->watchdog_timeo = HZ*3;
-
- if (dev_alloc_name(dev, ifname) < 0) {
- DMESG("Oops: devname already taken! Trying wlan%%d...\n");
- strcpy(ifname, "wlan%d");
- dev_alloc_name(dev, ifname);
- }
-
- if (rtl8180_init(dev) != 0) {
- DMESG("Initialization failed");
- goto fail1;
- }
-
- netif_carrier_off(dev);
-
- if (register_netdev(dev))
- goto fail1;
-
- rtl8180_proc_init_one(dev);
-
- DMESG("Driver probe completed\n");
- return 0;
-fail1:
- if (dev->mem_start != (unsigned long)NULL) {
- iounmap((void __iomem *)dev->mem_start);
- release_mem_region(pci_resource_start(pdev, 1),
- pci_resource_len(pdev, 1));
- }
-fail:
- if (dev) {
- if (priv->irq) {
- free_irq(dev->irq, dev);
- dev->irq = 0;
- }
- free_ieee80211(dev);
- }
-
-fail_free:
- pci_disable_device(pdev);
-
- DMESG("wlan driver load failed\n");
- return ret;
-}
-
-static void rtl8180_pci_remove(struct pci_dev *pdev)
-{
- struct r8180_priv *priv;
- struct net_device *dev = pci_get_drvdata(pdev);
-
- if (dev) {
- unregister_netdev(dev);
-
- priv = ieee80211_priv(dev);
-
- rtl8180_proc_remove_one(dev);
- rtl8180_down(dev);
- priv->rf_close(dev);
- rtl8180_reset(dev);
- mdelay(10);
-
- if (priv->irq) {
- DMESG("Freeing irq %d", dev->irq);
- free_irq(dev->irq, dev);
- priv->irq = 0;
- }
-
- free_rx_desc_ring(dev);
- free_tx_desc_rings(dev);
-
- if (dev->mem_start != (unsigned long)NULL) {
- iounmap((void __iomem *)dev->mem_start);
- release_mem_region(pci_resource_start(pdev, 1),
- pci_resource_len(pdev, 1));
- }
-
- free_ieee80211(dev);
- }
- pci_disable_device(pdev);
-
- DMESG("wlan driver removed\n");
-}
-
-static int __init rtl8180_pci_module_init(void)
-{
- int ret;
-
- ret = ieee80211_crypto_init();
- if (ret) {
- pr_err("ieee80211_crypto_init() failed %d\n", ret);
- return ret;
- }
- ret = ieee80211_crypto_tkip_init();
- if (ret) {
- pr_err("ieee80211_crypto_tkip_init() failed %d\n", ret);
- return ret;
- }
- ret = ieee80211_crypto_ccmp_init();
- if (ret) {
- pr_err("ieee80211_crypto_ccmp_init() failed %d\n", ret);
- return ret;
- }
- ret = ieee80211_crypto_wep_init();
- if (ret) {
- pr_err("ieee80211_crypto_wep_init() failed %d\n", ret);
- return ret;
- }
-
- pr_info("\nLinux kernel driver for RTL8180 / RTL8185 based WLAN cards\n");
- pr_info("Copyright (c) 2004-2005, Andrea Merello\n");
- DMESG("Initializing module");
- DMESG("Wireless extensions version %d", WIRELESS_EXT);
- rtl8180_proc_module_init();
-
- if (pci_register_driver(&rtl8180_pci_driver)) {
- DMESG("No device found");
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit rtl8180_pci_module_exit(void)
-{
- pci_unregister_driver(&rtl8180_pci_driver);
- rtl8180_proc_module_remove();
- ieee80211_crypto_tkip_exit();
- ieee80211_crypto_ccmp_exit();
- ieee80211_crypto_wep_exit();
- ieee80211_crypto_deinit();
- DMESG("Exiting");
-}
-
-static void rtl8180_try_wake_queue(struct net_device *dev, int pri)
-{
- unsigned long flags;
- short enough_desc;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- spin_lock_irqsave(&priv->tx_lock, flags);
- enough_desc = check_nic_enought_desc(dev, pri);
- spin_unlock_irqrestore(&priv->tx_lock, flags);
-
- if (enough_desc)
- ieee80211_rtl_wake_queue(priv->ieee80211);
-}
-
-static void rtl8180_tx_isr(struct net_device *dev, int pri, short error)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u32 *tail; /* tail virtual addr */
- u32 *head; /* head virtual addr */
- u32 *begin; /* start of ring virtual addr */
- u32 *nicv; /* nic pointer virtual addr */
- u32 nic; /* nic pointer physical addr */
- u32 nicbegin; /* start of ring physical addr */
- unsigned long flag;
- /* physical addr are ok on 32 bits since we set DMA mask */
- int offs;
- int j, i;
- int hd;
- if (error)
- priv->stats.txretry++;
- spin_lock_irqsave(&priv->tx_lock, flag);
- switch (pri) {
- case MANAGE_PRIORITY:
- tail = priv->txmapringtail;
- begin = priv->txmapring;
- head = priv->txmapringhead;
- nic = read_nic_dword(dev, TX_MANAGEPRIORITY_RING_ADDR);
- nicbegin = priv->txmapringdma;
- break;
- case BK_PRIORITY:
- tail = priv->txbkpringtail;
- begin = priv->txbkpring;
- head = priv->txbkpringhead;
- nic = read_nic_dword(dev, TX_BKPRIORITY_RING_ADDR);
- nicbegin = priv->txbkpringdma;
- break;
- case BE_PRIORITY:
- tail = priv->txbepringtail;
- begin = priv->txbepring;
- head = priv->txbepringhead;
- nic = read_nic_dword(dev, TX_BEPRIORITY_RING_ADDR);
- nicbegin = priv->txbepringdma;
- break;
- case VI_PRIORITY:
- tail = priv->txvipringtail;
- begin = priv->txvipring;
- head = priv->txvipringhead;
- nic = read_nic_dword(dev, TX_VIPRIORITY_RING_ADDR);
- nicbegin = priv->txvipringdma;
- break;
- case VO_PRIORITY:
- tail = priv->txvopringtail;
- begin = priv->txvopring;
- head = priv->txvopringhead;
- nic = read_nic_dword(dev, TX_VOPRIORITY_RING_ADDR);
- nicbegin = priv->txvopringdma;
- break;
- case HI_PRIORITY:
- tail = priv->txhpringtail;
- begin = priv->txhpring;
- head = priv->txhpringhead;
- nic = read_nic_dword(dev, TX_HIGHPRIORITY_RING_ADDR);
- nicbegin = priv->txhpringdma;
- break;
-
- default:
- spin_unlock_irqrestore(&priv->tx_lock, flag);
- return;
- }
-
- nicv = (u32 *)((nic - nicbegin) + (u8 *)begin);
- if ((head <= tail && (nicv > tail || nicv < head)) ||
- (head > tail && (nicv > tail && nicv < head))) {
- DMESGW("nic has lost pointer");
- spin_unlock_irqrestore(&priv->tx_lock, flag);
- rtl8180_restart(dev);
- return;
- }
-
- /*
- * We check all the descriptors between the head and the nic,
- * but not the currently pointed by the nic (the next to be txed)
- * and the previous of the pointed (might be in process ??)
- */
- offs = (nic - nicbegin);
- offs = offs / 8 / 4;
- hd = (head - begin) / 8;
-
- if (offs >= hd)
- j = offs - hd;
- else
- j = offs + (priv->txringcount-1-hd);
-
- j -= 2;
- if (j < 0)
- j = 0;
-
- for (i = 0; i < j; i++) {
- if ((*head) & (1<<31))
- break;
- if (((*head)&(0x10000000)) != 0) {
- priv->CurrRetryCnt += (u16)((*head) & (0x000000ff));
- if (!error)
- priv->NumTxOkTotal++;
- }
-
- if (!error)
- priv->NumTxOkBytesTotal += (*(head+3)) & (0x00000fff);
-
- *head = *head & ~(1<<31);
-
- if ((head - begin)/8 == priv->txringcount-1)
- head = begin;
- else
- head += 8;
- }
-
- /*
- * The head has been moved to the last certainly TXed
- * (or at least processed by the nic) packet.
- * The driver take forcefully owning of all these packets
- * If the packet previous of the nic pointer has been
- * processed this doesn't matter: it will be checked
- * here at the next round. Anyway if no more packet are
- * TXed no memory leak occur at all.
- */
-
- switch (pri) {
- case MANAGE_PRIORITY:
- priv->txmapringhead = head;
-
- if (priv->ack_tx_to_ieee) {
- if (rtl8180_is_tx_queue_empty(dev)) {
- priv->ack_tx_to_ieee = 0;
- ieee80211_ps_tx_ack(priv->ieee80211, !error);
- }
- }
- break;
- case BK_PRIORITY:
- priv->txbkpringhead = head;
- break;
- case BE_PRIORITY:
- priv->txbepringhead = head;
- break;
- case VI_PRIORITY:
- priv->txvipringhead = head;
- break;
- case VO_PRIORITY:
- priv->txvopringhead = head;
- break;
- case HI_PRIORITY:
- priv->txhpringhead = head;
- break;
- }
-
- spin_unlock_irqrestore(&priv->tx_lock, flag);
-}
-
-static irqreturn_t rtl8180_interrupt(int irq, void *netdev)
-{
- struct net_device *dev = (struct net_device *) netdev;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- unsigned long flags;
- u32 inta;
-
- /* We should return IRQ_NONE, but for now let me keep this */
- if (priv->irq_enabled == 0)
- return IRQ_HANDLED;
-
- spin_lock_irqsave(&priv->irq_th_lock, flags);
-
- /* ISR: 4bytes */
- inta = read_nic_dword(dev, ISR);
- write_nic_dword(dev, ISR, inta); /* reset int situation */
-
- priv->stats.shints++;
-
- if (!inta) {
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
- return IRQ_HANDLED;
- /*
- * most probably we can safely return IRQ_NONE,
- * but for now is better to avoid problems
- */
- }
-
- if (inta == 0xffff) {
- /* HW disappeared */
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
- return IRQ_HANDLED;
- }
-
- priv->stats.ints++;
-
- if (!netif_running(dev)) {
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
- return IRQ_HANDLED;
- }
-
- if (inta & ISR_TimeOut)
- write_nic_dword(dev, TimerInt, 0);
-
- if (inta & ISR_TBDOK)
- priv->stats.txbeacon++;
-
- if (inta & ISR_TBDER)
- priv->stats.txbeaconerr++;
-
- if (inta & IMR_TMGDOK)
- rtl8180_tx_isr(dev, MANAGE_PRIORITY, 0);
-
- if (inta & ISR_THPDER) {
- priv->stats.txhperr++;
- rtl8180_tx_isr(dev, HI_PRIORITY, 1);
- priv->ieee80211->stats.tx_errors++;
- }
-
- if (inta & ISR_THPDOK) { /* High priority tx ok */
- priv->link_detect.num_tx_ok_in_period++;
- priv->stats.txhpokint++;
- rtl8180_tx_isr(dev, HI_PRIORITY, 0);
- }
-
- if (inta & ISR_RER)
- priv->stats.rxerr++;
-
- if (inta & ISR_TBKDER) { /* corresponding to BK_PRIORITY */
- priv->stats.txbkperr++;
- priv->ieee80211->stats.tx_errors++;
- rtl8180_tx_isr(dev, BK_PRIORITY, 1);
- rtl8180_try_wake_queue(dev, BK_PRIORITY);
- }
-
- if (inta & ISR_TBEDER) { /* corresponding to BE_PRIORITY */
- priv->stats.txbeperr++;
- priv->ieee80211->stats.tx_errors++;
- rtl8180_tx_isr(dev, BE_PRIORITY, 1);
- rtl8180_try_wake_queue(dev, BE_PRIORITY);
- }
- if (inta & ISR_TNPDER) { /* corresponding to VO_PRIORITY */
- priv->stats.txnperr++;
- priv->ieee80211->stats.tx_errors++;
- rtl8180_tx_isr(dev, NORM_PRIORITY, 1);
- rtl8180_try_wake_queue(dev, NORM_PRIORITY);
- }
-
- if (inta & ISR_TLPDER) { /* corresponding to VI_PRIORITY */
- priv->stats.txlperr++;
- priv->ieee80211->stats.tx_errors++;
- rtl8180_tx_isr(dev, LOW_PRIORITY, 1);
- rtl8180_try_wake_queue(dev, LOW_PRIORITY);
- }
-
- if (inta & ISR_ROK) {
- priv->stats.rxint++;
- tasklet_schedule(&priv->irq_rx_tasklet);
- }
-
- if (inta & ISR_RQoSOK) {
- priv->stats.rxint++;
- tasklet_schedule(&priv->irq_rx_tasklet);
- }
-
- if (inta & ISR_BcnInt)
- rtl8180_prepare_beacon(dev);
-
- if (inta & ISR_RDU) {
- DMESGW("No RX descriptor available");
- priv->stats.rxrdu++;
- tasklet_schedule(&priv->irq_rx_tasklet);
- }
-
- if (inta & ISR_RXFOVW) {
- priv->stats.rxoverflow++;
- tasklet_schedule(&priv->irq_rx_tasklet);
- }
-
- if (inta & ISR_TXFOVW)
- priv->stats.txoverflow++;
-
- if (inta & ISR_TNPDOK) { /* Normal priority tx ok */
- priv->link_detect.num_tx_ok_in_period++;
- priv->stats.txnpokint++;
- rtl8180_tx_isr(dev, NORM_PRIORITY, 0);
- rtl8180_try_wake_queue(dev, NORM_PRIORITY);
- }
-
- if (inta & ISR_TLPDOK) { /* Low priority tx ok */
- priv->link_detect.num_tx_ok_in_period++;
- priv->stats.txlpokint++;
- rtl8180_tx_isr(dev, LOW_PRIORITY, 0);
- rtl8180_try_wake_queue(dev, LOW_PRIORITY);
- }
-
- if (inta & ISR_TBKDOK) { /* corresponding to BK_PRIORITY */
- priv->stats.txbkpokint++;
- priv->link_detect.num_tx_ok_in_period++;
- rtl8180_tx_isr(dev, BK_PRIORITY, 0);
- rtl8180_try_wake_queue(dev, BE_PRIORITY);
- }
-
- if (inta & ISR_TBEDOK) { /* corresponding to BE_PRIORITY */
- priv->stats.txbeperr++;
- priv->link_detect.num_tx_ok_in_period++;
- rtl8180_tx_isr(dev, BE_PRIORITY, 0);
- rtl8180_try_wake_queue(dev, BE_PRIORITY);
- }
- force_pci_posting(dev);
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
-
- return IRQ_HANDLED;
-}
-
-void rtl8180_irq_rx_tasklet(struct r8180_priv *priv)
-{
- rtl8180_rx(priv->dev);
-}
-
-void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(
- work, struct ieee80211_device, GPIOChangeRFWorkItem.work);
- struct net_device *dev = ieee->dev;
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 btPSR;
- u8 btConfig0;
- enum rt_rf_power_state eRfPowerStateToSet;
- bool bActuallySet = false;
-
- char *argv[3];
- static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
- static char *envp[] = {"HOME=/", "TERM=linux",
- "PATH=/usr/bin:/bin", NULL};
- static int readf_count;
-
- readf_count = (readf_count+1)%0xffff;
- /* We should turn off LED before polling FF51[4]. */
-
- /* Turn off LED. */
- btPSR = read_nic_byte(dev, PSR);
- write_nic_byte(dev, PSR, (btPSR & ~BIT3));
-
- /* It need to delay 4us suggested */
- udelay(4);
-
- /* HW radio On/Off according to the value of FF51[4](config0) */
- btConfig0 = btPSR = read_nic_byte(dev, CONFIG0);
-
- eRfPowerStateToSet = (btConfig0 & BIT4) ? RF_ON : RF_OFF;
-
- /* Turn LED back on when radio enabled */
- if (eRfPowerStateToSet == RF_ON)
- write_nic_byte(dev, PSR, btPSR | BIT3);
-
- if ((priv->ieee80211->bHwRadioOff == true) &&
- (eRfPowerStateToSet == RF_ON)) {
- priv->ieee80211->bHwRadioOff = false;
- bActuallySet = true;
- } else if ((priv->ieee80211->bHwRadioOff == false) &&
- (eRfPowerStateToSet == RF_OFF)) {
- priv->ieee80211->bHwRadioOff = true;
- bActuallySet = true;
- }
-
- if (bActuallySet) {
- MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
-
- /* To update the UI status for Power status changed */
- if (priv->ieee80211->bHwRadioOff == true)
- argv[1] = "RFOFF";
- else
- argv[1] = "RFON";
- argv[0] = RadioPowerPath;
- argv[2] = NULL;
-
- call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
- }
-}
-
-module_init(rtl8180_pci_module_init);
-module_exit(rtl8180_pci_module_exit);
+++ /dev/null
-#include "r8180_dm.h"
-#include "r8180_hw.h"
-#include "r8180_93cx6.h"
-
- /* Return TRUE if we shall perform High Power Mechanism, FALSE otherwise. */
-#define RATE_ADAPTIVE_TIMER_PERIOD 300
-
-bool CheckHighPower(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
-
- if (!priv->bRegHighPowerMechanism)
- return false;
-
- if (ieee->state == IEEE80211_LINKED_SCANNING)
- return false;
-
- return true;
-}
-
-/*
- * Description:
- * Update Tx power level if necessary.
- * See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
- *
- * Note:
- * The reason why we udpate Tx power level here instead of DoRxHighPower()
- * is the number of IO to change Tx power is much more than channel TR switch
- * and they are related to OFDM and MAC registers.
- * So, we don't want to update it so frequently in per-Rx packet base.
- */
-static void DoTxHighPower(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 HiPwrUpperTh = 0;
- u16 HiPwrLowerTh = 0;
- u8 RSSIHiPwrUpperTh;
- u8 RSSIHiPwrLowerTh;
- u8 u1bTmp;
- char OfdmTxPwrIdx, CckTxPwrIdx;
-
- HiPwrUpperTh = priv->RegHiPwrUpperTh;
- HiPwrLowerTh = priv->RegHiPwrLowerTh;
-
- HiPwrUpperTh = HiPwrUpperTh * 10;
- HiPwrLowerTh = HiPwrLowerTh * 10;
- RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;
- RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;
-
- /* lzm add 080826 */
- OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
- CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
-
- if ((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
- (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh))) {
- /* Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah */
-
- priv->bToUpdateTxPwr = true;
- u1bTmp = read_nic_byte(dev, CCK_TXAGC);
-
- /* If it never enter High Power. */
- if (CckTxPwrIdx == u1bTmp) {
- u1bTmp = (u1bTmp > 16) ? (u1bTmp - 16) : 0; /* 8dbm */
- write_nic_byte(dev, CCK_TXAGC, u1bTmp);
-
- u1bTmp = read_nic_byte(dev, OFDM_TXAGC);
- u1bTmp = (u1bTmp > 16) ? (u1bTmp - 16) : 0; /* 8dbm */
- write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
- }
-
- } else if ((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
- (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh)) {
- if (priv->bToUpdateTxPwr) {
- priv->bToUpdateTxPwr = false;
- /* SD3 required. */
- u1bTmp = read_nic_byte(dev, CCK_TXAGC);
- if (u1bTmp < CckTxPwrIdx) {
- write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
- }
-
- u1bTmp = read_nic_byte(dev, OFDM_TXAGC);
- if (u1bTmp < OfdmTxPwrIdx) {
- write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
- }
- }
- }
-}
-
-
-/*
- * Description:
- * Callback function of UpdateTxPowerWorkItem.
- * Because of some event happened, e.g. CCX TPC, High Power Mechanism,
- * We update Tx power of current channel again.
- */
-void rtl8180_tx_pw_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, tx_pw_wq);
- struct net_device *dev = ieee->dev;
-
- DoTxHighPower(dev);
-}
-
-
-/*
- * Return TRUE if we shall perform DIG Mechanism, FALSE otherwise.
- */
-bool CheckDig(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
-
- if (!priv->bDigMechanism)
- return false;
-
- if (ieee->state != IEEE80211_LINKED)
- return false;
-
- if ((priv->ieee80211->rate / 5) < 36) /* Schedule Dig under all OFDM rates. By Bruce, 2007-06-01. */
- return false;
- return true;
-}
-/*
- * Implementation of DIG for Zebra and Zebra2.
- */
-static void DIG_Zebra(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 CCKFalseAlarm, OFDMFalseAlarm;
- u16 OfdmFA1, OfdmFA2;
- int InitialGainStep = 7; /* The number of initial gain stages. */
- int LowestGainStage = 4; /* The capable lowest stage of performing dig workitem. */
- u32 AwakePeriodIn2Sec = 0;
-
- CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
- OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
- OfdmFA1 = 0x15;
- OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
-
- /* The number of initial gain steps is different, by Bruce, 2007-04-13. */
- if (priv->InitialGain == 0) { /* autoDIG */
- /* Advised from SD3 DZ */
- priv->InitialGain = 4; /* In 87B, m74dBm means State 4 (m82dBm) */
- }
- /* Advised from SD3 DZ */
- OfdmFA1 = 0x20;
-
-#if 1 /* lzm reserved 080826 */
- AwakePeriodIn2Sec = (2000 - priv->DozePeriodInPast2Sec);
- priv->DozePeriodInPast2Sec = 0;
-
- if (AwakePeriodIn2Sec) {
- OfdmFA1 = (u16)((OfdmFA1 * AwakePeriodIn2Sec) / 2000);
- OfdmFA2 = (u16)((OfdmFA2 * AwakePeriodIn2Sec) / 2000);
- } else {
- ;
- }
-#endif
-
- InitialGainStep = 8;
- LowestGainStage = priv->RegBModeGainStage; /* Lowest gain stage. */
-
- if (OFDMFalseAlarm > OfdmFA1) {
- if (OFDMFalseAlarm > OfdmFA2) {
- priv->DIG_NumberFallbackVote++;
- if (priv->DIG_NumberFallbackVote > 1) {
- /* serious OFDM False Alarm, need fallback */
- if (priv->InitialGain < InitialGainStep) {
- priv->InitialGainBackUp = priv->InitialGain;
-
- priv->InitialGain = (priv->InitialGain + 1);
- UpdateInitialGain(dev);
- }
- priv->DIG_NumberFallbackVote = 0;
- priv->DIG_NumberUpgradeVote = 0;
- }
- } else {
- if (priv->DIG_NumberFallbackVote)
- priv->DIG_NumberFallbackVote--;
- }
- priv->DIG_NumberUpgradeVote = 0;
- } else {
- if (priv->DIG_NumberFallbackVote)
- priv->DIG_NumberFallbackVote--;
- priv->DIG_NumberUpgradeVote++;
-
- if (priv->DIG_NumberUpgradeVote > 9) {
- if (priv->InitialGain > LowestGainStage) { /* In 87B, m78dBm means State 4 (m864dBm) */
- priv->InitialGainBackUp = priv->InitialGain;
-
- priv->InitialGain = (priv->InitialGain - 1);
- UpdateInitialGain(dev);
- }
- priv->DIG_NumberFallbackVote = 0;
- priv->DIG_NumberUpgradeVote = 0;
- }
- }
-}
-
-/*
- * Dispatch DIG implementation according to RF.
- */
-static void DynamicInitGain(struct net_device *dev)
-{
- DIG_Zebra(dev);
-}
-
-void rtl8180_hw_dig_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, hw_dig_wq);
- struct net_device *dev = ieee->dev;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- /* Read CCK and OFDM False Alarm. */
- priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
-
-
- /* Adjust Initial Gain dynamically. */
- DynamicInitGain(dev);
-
-}
-
-static int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
-{
- u8 rate_len;
- u8 rate_ex_len;
- u8 RateMask = 0x7F;
- u8 idx;
- unsigned short Found = 0;
- u8 NaiveTxRate = TxRate&RateMask;
-
- rate_len = priv->ieee80211->current_network.rates_len;
- rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
- for (idx = 0; idx < rate_len; idx++) {
- if ((priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate) {
- Found = 1;
- goto found_rate;
- }
- }
- for (idx = 0; idx < rate_ex_len; idx++) {
- if ((priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate) {
- Found = 1;
- goto found_rate;
- }
- }
- return Found;
-found_rate:
- return Found;
-}
-
-/*
- * Get the Tx rate one degree up form the input rate in the supported rates.
- * Return the upgrade rate if it is successed, otherwise return the input rate.
- */
-static u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 UpRate;
-
- /* Upgrade 1 degree. */
- switch (rate) {
- case 108: /* Up to 54Mbps. */
- UpRate = 108;
- break;
-
- case 96: /* Up to 54Mbps. */
- UpRate = 108;
- break;
-
- case 72: /* Up to 48Mbps. */
- UpRate = 96;
- break;
-
- case 48: /* Up to 36Mbps. */
- UpRate = 72;
- break;
-
- case 36: /* Up to 24Mbps. */
- UpRate = 48;
- break;
-
- case 22: /* Up to 18Mbps. */
- UpRate = 36;
- break;
-
- case 11: /* Up to 11Mbps. */
- UpRate = 22;
- break;
-
- case 4: /* Up to 5.5Mbps. */
- UpRate = 11;
- break;
-
- case 2: /* Up to 2Mbps. */
- UpRate = 4;
- break;
-
- default:
- printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
- return rate;
- }
- /* Check if the rate is valid. */
- if (IncludedInSupportedRates(priv, UpRate)) {
- return UpRate;
- } else {
- return rate;
- }
- return rate;
-}
-/*
- * Get the Tx rate one degree down form the input rate in the supported rates.
- * Return the degrade rate if it is successed, otherwise return the input rate.
- */
-
-static u8 GetDegradeTxRate(struct net_device *dev, u8 rate)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 DownRate;
-
- /* Upgrade 1 degree. */
- switch (rate) {
- case 108: /* Down to 48Mbps. */
- DownRate = 96;
- break;
-
- case 96: /* Down to 36Mbps. */
- DownRate = 72;
- break;
-
- case 72: /* Down to 24Mbps. */
- DownRate = 48;
- break;
-
- case 48: /* Down to 18Mbps. */
- DownRate = 36;
- break;
-
- case 36: /* Down to 11Mbps. */
- DownRate = 22;
- break;
-
- case 22: /* Down to 5.5Mbps. */
- DownRate = 11;
- break;
-
- case 11: /* Down to 2Mbps. */
- DownRate = 4;
- break;
-
- case 4: /* Down to 1Mbps. */
- DownRate = 2;
- break;
-
- case 2: /* Down to 1Mbps. */
- DownRate = 2;
- break;
-
- default:
- printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
- return rate;
- }
- /* Check if the rate is valid. */
- if (IncludedInSupportedRates(priv, DownRate)) {
- return DownRate;
- } else {
- return rate;
- }
- return rate;
-}
-/*
- * Helper function to determine if specified data rate is
- * CCK rate.
- */
-
-static bool MgntIsCckRate(u16 rate)
-{
- bool bReturn = false;
-
- if ((rate <= 22) && (rate != 12) && (rate != 18)) {
- bReturn = true;
- }
-
- return bReturn;
-}
-/*
- * Description:
- * Tx Power tracking mechanism routine on 87SE.
- */
-void TxPwrTracking87SE(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u8 tmpu1Byte, CurrentThermal, Idx;
- char CckTxPwrIdx, OfdmTxPwrIdx;
-
- tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
- CurrentThermal = (tmpu1Byte & 0xf0) >> 4; /*[ 7:4]: thermal meter indication. */
- CurrentThermal = (CurrentThermal > 0x0c) ? 0x0c : CurrentThermal;/* lzm add 080826 */
-
- if (CurrentThermal != priv->ThermalMeter) {
- /* Update Tx Power level on each channel. */
- for (Idx = 1; Idx < 15; Idx++) {
- CckTxPwrIdx = priv->chtxpwr[Idx];
- OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
-
- if (CurrentThermal > priv->ThermalMeter) {
- /* higher thermal meter. */
- CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter) * 2;
- OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter) * 2;
-
- if (CckTxPwrIdx > 35)
- CckTxPwrIdx = 35; /* Force TxPower to maximal index. */
- if (OfdmTxPwrIdx > 35)
- OfdmTxPwrIdx = 35;
- } else {
- /* lower thermal meter. */
- CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2;
- OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2;
-
- if (CckTxPwrIdx < 0)
- CckTxPwrIdx = 0;
- if (OfdmTxPwrIdx < 0)
- OfdmTxPwrIdx = 0;
- }
-
- /* Update TxPower level on CCK and OFDM resp. */
- priv->chtxpwr[Idx] = CckTxPwrIdx;
- priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
- }
-
- /* Update TxPower level immediately. */
- rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
- }
- priv->ThermalMeter = CurrentThermal;
-}
-static void StaRateAdaptive87SE(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- unsigned long CurrTxokCnt;
- u16 CurrRetryCnt;
- u16 CurrRetryRate;
- unsigned long CurrRxokCnt;
- bool bTryUp = false;
- bool bTryDown = false;
- u8 TryUpTh = 1;
- u8 TryDownTh = 2;
- u32 TxThroughput;
- long CurrSignalStrength;
- bool bUpdateInitialGain = false;
- u8 u1bOfdm = 0, u1bCck = 0;
- char OfdmTxPwrIdx, CckTxPwrIdx;
-
- priv->RateAdaptivePeriod = RATE_ADAPTIVE_TIMER_PERIOD;
-
-
- CurrRetryCnt = priv->CurrRetryCnt;
- CurrTxokCnt = priv->NumTxOkTotal - priv->LastTxokCnt;
- CurrRxokCnt = priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;
- CurrSignalStrength = priv->Stats_RecvSignalPower;
- TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);
- priv->LastTxOKBytes = priv->NumTxOkBytesTotal;
- priv->CurrentOperaRate = priv->ieee80211->rate / 5;
- /* 2 Compute retry ratio. */
- if (CurrTxokCnt > 0) {
- CurrRetryRate = (u16)(CurrRetryCnt * 100 / CurrTxokCnt);
- } else {
- /* It may be serious retry. To distinguish serious retry or no packets modified by Bruce */
- CurrRetryRate = (u16)(CurrRetryCnt * 100 / 1);
- }
-
- priv->LastRetryCnt = priv->CurrRetryCnt;
- priv->LastTxokCnt = priv->NumTxOkTotal;
- priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
- priv->CurrRetryCnt = 0;
-
- /* 2No Tx packets, return to init_rate or not? */
- if (CurrRetryRate == 0 && CurrTxokCnt == 0) {
- /*
- * After 9 (30*300ms) seconds in this condition, we try to raise rate.
- */
- priv->TryupingCountNoData++;
-
- /* [TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00 */
- if (priv->TryupingCountNoData > 30) {
- priv->TryupingCountNoData = 0;
- priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
- /* Reset Fail Record */
- priv->LastFailTxRate = 0;
- priv->LastFailTxRateSS = -200;
- priv->FailTxRateCount = 0;
- }
- goto SetInitialGain;
- } else {
- priv->TryupingCountNoData = 0; /*Reset trying up times. */
- }
-
-
- /*
- * For Netgear case, I comment out the following signal strength estimation,
- * which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
- *
- * Restructure rate adaptive as the following main stages:
- * (1) Add retry threshold in 54M upgrading condition with signal strength.
- * (2) Add the mechanism to degrade to CCK rate according to signal strength
- * and retry rate.
- * (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
- * situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
- * (4) Add the mechanism of trying to upgrade tx rate.
- * (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
- *
- */
-
- /*
- * 11Mbps or 36Mbps
- * Check more times in these rate(key rates).
- */
- if (priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
- TryUpTh += 9;
- /*
- * Let these rates down more difficult.
- */
- if (MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
- TryDownTh += 1;
-
- /* 1 Adjust Rate. */
- if (priv->bTryuping == true) {
- /* 2 For Test Upgrading mechanism
- * Note:
- * Sometimes the throughput is upon on the capability between the AP and NIC,
- * thus the low data rate does not improve the performance.
- * We randomly upgrade the data rate and check if the retry rate is improved.
- */
-
- /* Upgrading rate did not improve the retry rate, fallback to the original rate. */
- if ((CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput) {
- /*Not necessary raising rate, fall back rate. */
- bTryDown = true;
- } else {
- priv->bTryuping = false;
- }
- } else if (CurrSignalStrength > -47 && (CurrRetryRate < 50)) {
- /*
- * 2For High Power
- *
- * Return to highest data rate, if signal strength is good enough.
- * SignalStrength threshold(-50dbm) is for RTL8186.
- * Revise SignalStrength threshold to -51dbm.
- */
- /* Also need to check retry rate for safety, by Bruce, 2007-06-05. */
- if (priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate) {
- bTryUp = true;
- /* Upgrade Tx Rate directly. */
- priv->TryupingCount += TryUpTh;
- }
-
- } else if (CurrTxokCnt > 9 && CurrTxokCnt < 100 && CurrRetryRate >= 600) {
- /*
- *2 For Serious Retry
- *
- * Traffic is not busy but our Tx retry is serious.
- */
- bTryDown = true;
- /* Let Rate Mechanism to degrade tx rate directly. */
- priv->TryDownCountLowData += TryDownTh;
- } else if (priv->CurrentOperaRate == 108) {
- /* 2For 54Mbps */
- /* Air Link */
- if ((CurrRetryRate > 26) && (priv->LastRetryRate > 25)) {
- bTryDown = true;
- }
- /* Cable Link */
- else if ((CurrRetryRate > 17) && (priv->LastRetryRate > 16) && (CurrSignalStrength > -72)) {
- bTryDown = true;
- }
-
- if (bTryDown && (CurrSignalStrength < -75)) /* cable link */
- priv->TryDownCountLowData += TryDownTh;
- } else if (priv->CurrentOperaRate == 96) {
- /* 2For 48Mbps */
- /* Air Link */
- if (((CurrRetryRate > 48) && (priv->LastRetryRate > 47))) {
- bTryDown = true;
- } else if (((CurrRetryRate > 21) && (priv->LastRetryRate > 20)) && (CurrSignalStrength > -74)) { /* Cable Link */
- /* Down to rate 36Mbps. */
- bTryDown = true;
- } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- } else if ((CurrRetryRate < 8) && (priv->LastRetryRate < 8)) { /* TO DO: need to consider (RSSI) */
- bTryUp = true;
- }
-
- if (bTryDown && (CurrSignalStrength < -75)) {
- priv->TryDownCountLowData += TryDownTh;
- }
- } else if (priv->CurrentOperaRate == 72) {
- /* 2For 36Mbps */
- if ((CurrRetryRate > 43) && (priv->LastRetryRate > 41)) {
- /* Down to rate 24Mbps. */
- bTryDown = true;
- } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- } else if ((CurrRetryRate < 15) && (priv->LastRetryRate < 16)) { /* TO DO: need to consider (RSSI) */
- bTryUp = true;
- }
-
- if (bTryDown && (CurrSignalStrength < -80))
- priv->TryDownCountLowData += TryDownTh;
-
- } else if (priv->CurrentOperaRate == 48) {
- /* 2For 24Mbps */
- /* Air Link */
- if (((CurrRetryRate > 63) && (priv->LastRetryRate > 62))) {
- bTryDown = true;
- } else if (((CurrRetryRate > 33) && (priv->LastRetryRate > 32)) && (CurrSignalStrength > -82)) { /* Cable Link */
- bTryDown = true;
- } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- } else if ((CurrRetryRate < 20) && (priv->LastRetryRate < 21)) { /* TO DO: need to consider (RSSI) */
- bTryUp = true;
- }
-
- if (bTryDown && (CurrSignalStrength < -82))
- priv->TryDownCountLowData += TryDownTh;
-
- } else if (priv->CurrentOperaRate == 36) {
- if (((CurrRetryRate > 85) && (priv->LastRetryRate > 86))) {
- bTryDown = true;
- } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- } else if ((CurrRetryRate < 22) && (priv->LastRetryRate < 23)) { /* TO DO: need to consider (RSSI) */
- bTryUp = true;
- }
- } else if (priv->CurrentOperaRate == 22) {
- /* 2For 11Mbps */
- if (CurrRetryRate > 95) {
- bTryDown = true;
- } else if ((CurrRetryRate < 29) && (priv->LastRetryRate < 30)) { /*TO DO: need to consider (RSSI) */
- bTryUp = true;
- }
- } else if (priv->CurrentOperaRate == 11) {
- /* 2For 5.5Mbps */
- if (CurrRetryRate > 149) {
- bTryDown = true;
- } else if ((CurrRetryRate < 60) && (priv->LastRetryRate < 65)) {
- bTryUp = true;
- }
- } else if (priv->CurrentOperaRate == 4) {
- /* 2For 2 Mbps */
- if ((CurrRetryRate > 99) && (priv->LastRetryRate > 99)) {
- bTryDown = true;
- } else if ((CurrRetryRate < 65) && (priv->LastRetryRate < 70)) {
- bTryUp = true;
- }
- } else if (priv->CurrentOperaRate == 2) {
- /* 2For 1 Mbps */
- if ((CurrRetryRate < 70) && (priv->LastRetryRate < 75)) {
- bTryUp = true;
- }
- }
-
- if (bTryUp && bTryDown)
- printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
-
- /* 1 Test Upgrading Tx Rate
- * Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
- * To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
- */
- if (!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
- && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2) {
- if (jiffies % (CurrRetryRate + 101) == 0) {
- bTryUp = true;
- priv->bTryuping = true;
- }
- }
-
- /* 1 Rate Mechanism */
- if (bTryUp) {
- priv->TryupingCount++;
- priv->TryDownCountLowData = 0;
-
- /*
- * Check more times if we need to upgrade indeed.
- * Because the largest value of pHalData->TryupingCount is 0xFFFF and
- * the largest value of pHalData->FailTxRateCount is 0x14,
- * this condition will be satisfied at most every 2 min.
- */
-
- if ((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
- (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping) {
- priv->TryupingCount = 0;
- /*
- * When transferring from CCK to OFDM, DIG is an important issue.
- */
- if (priv->CurrentOperaRate == 22)
- bUpdateInitialGain = true;
-
- /*
- * The difference in throughput between 48Mbps and 36Mbps is 8M.
- * So, we must be careful in this rate scale. Isaiah 2008-02-15.
- */
- if (((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
- (priv->FailTxRateCount > 2))
- priv->RateAdaptivePeriod = (RATE_ADAPTIVE_TIMER_PERIOD / 2);
-
- /* (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold. */
- /* (2)If the signal strength is increased, it may be able to upgrade. */
-
- priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
-
- if (priv->CurrentOperaRate == 36) {
- priv->bUpdateARFR = true;
- write_nic_word(dev, ARFR, 0x0F8F); /* bypass 12/9/6 */
- } else if (priv->bUpdateARFR) {
- priv->bUpdateARFR = false;
- write_nic_word(dev, ARFR, 0x0FFF); /* set 1M ~ 54Mbps. */
- }
-
- /* Update Fail Tx rate and count. */
- if (priv->LastFailTxRate != priv->CurrentOperaRate) {
- priv->LastFailTxRate = priv->CurrentOperaRate;
- priv->FailTxRateCount = 0;
- priv->LastFailTxRateSS = -200; /* Set lowest power. */
- }
- }
- } else {
- if (priv->TryupingCount > 0)
- priv->TryupingCount--;
- }
-
- if (bTryDown) {
- priv->TryDownCountLowData++;
- priv->TryupingCount = 0;
-
- /* Check if Tx rate can be degraded or Test trying upgrading should fallback. */
- if (priv->TryDownCountLowData > TryDownTh || priv->bTryuping) {
- priv->TryDownCountLowData = 0;
- priv->bTryuping = false;
- /* Update fail information. */
- if (priv->LastFailTxRate == priv->CurrentOperaRate) {
- priv->FailTxRateCount++;
- /* Record the Tx fail rate signal strength. */
- if (CurrSignalStrength > priv->LastFailTxRateSS)
- priv->LastFailTxRateSS = CurrSignalStrength;
- } else {
- priv->LastFailTxRate = priv->CurrentOperaRate;
- priv->FailTxRateCount = 1;
- priv->LastFailTxRateSS = CurrSignalStrength;
- }
- priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
-
- /* Reduce chariot training time at weak signal strength situation. SD3 ED demand. */
- if ((CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72)) {
- priv->CurrentOperaRate = 72;
- }
-
- if (priv->CurrentOperaRate == 36) {
- priv->bUpdateARFR = true;
- write_nic_word(dev, ARFR, 0x0F8F); /* bypass 12/9/6 */
- } else if (priv->bUpdateARFR) {
- priv->bUpdateARFR = false;
- write_nic_word(dev, ARFR, 0x0FFF); /* set 1M ~ 54Mbps. */
- }
-
- /*
- * When it is CCK rate, it may need to update initial gain to receive lower power packets.
- */
- if (MgntIsCckRate(priv->CurrentOperaRate)) {
- bUpdateInitialGain = true;
- }
- }
- } else {
- if (priv->TryDownCountLowData > 0)
- priv->TryDownCountLowData--;
- }
-
- /*
- * Keep the Tx fail rate count to equal to 0x15 at most.
- * Reduce the fail count at least to 10 sec if tx rate is tending stable.
- */
- if (priv->FailTxRateCount >= 0x15 ||
- (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6)) {
- priv->FailTxRateCount--;
- }
-
-
- OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
- CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
-
- /* Mac0x9e increase 2 level in 36M~18M situation */
- if ((priv->CurrentOperaRate < 96) && (priv->CurrentOperaRate > 22)) {
- u1bCck = read_nic_byte(dev, CCK_TXAGC);
- u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
-
- /* case 1: Never enter High power */
- if (u1bCck == CckTxPwrIdx) {
- if (u1bOfdm != (OfdmTxPwrIdx + 2)) {
- priv->bEnhanceTxPwr = true;
- u1bOfdm = ((u1bOfdm + 2) > 35) ? 35 : (u1bOfdm + 2);
- write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
- }
- } else if (u1bCck < CckTxPwrIdx) {
- /* case 2: enter high power */
- if (!priv->bEnhanceTxPwr) {
- priv->bEnhanceTxPwr = true;
- u1bOfdm = ((u1bOfdm + 2) > 35) ? 35 : (u1bOfdm + 2);
- write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
- }
- }
- } else if (priv->bEnhanceTxPwr) { /* 54/48/11/5.5/2/1 */
- u1bCck = read_nic_byte(dev, CCK_TXAGC);
- u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
-
- /* case 1: Never enter High power */
- if (u1bCck == CckTxPwrIdx) {
- priv->bEnhanceTxPwr = false;
- write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
- }
- /* case 2: enter high power */
- else if (u1bCck < CckTxPwrIdx) {
- priv->bEnhanceTxPwr = false;
- u1bOfdm = ((u1bOfdm - 2) > 0) ? (u1bOfdm - 2) : 0;
- write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
- }
- }
-
- /*
- * We need update initial gain when we set tx rate "from OFDM to CCK" or
- * "from CCK to OFDM".
- */
-SetInitialGain:
- if (bUpdateInitialGain) {
- if (MgntIsCckRate(priv->CurrentOperaRate)) { /* CCK */
- if (priv->InitialGain > priv->RegBModeGainStage) {
- priv->InitialGainBackUp = priv->InitialGain;
-
- if (CurrSignalStrength < -85) /* Low power, OFDM [0x17] = 26. */
- /* SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26. */
- priv->InitialGain = priv->RegBModeGainStage;
-
- else if (priv->InitialGain > priv->RegBModeGainStage + 1)
- priv->InitialGain -= 2;
-
- else
- priv->InitialGain--;
-
- printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n", priv->InitialGain, priv->CurrentOperaRate);
- UpdateInitialGain(dev);
- }
- } else { /* OFDM */
- if (priv->InitialGain < 4) {
- priv->InitialGainBackUp = priv->InitialGain;
-
- priv->InitialGain++;
- printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n", priv->InitialGain, priv->CurrentOperaRate);
- UpdateInitialGain(dev);
- }
- }
- }
-
- /* Record the related info */
- priv->LastRetryRate = CurrRetryRate;
- priv->LastTxThroughput = TxThroughput;
- priv->ieee80211->rate = priv->CurrentOperaRate * 5;
-}
-
-void rtl8180_rate_adapter(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, rate_adapter_wq);
- struct net_device *dev = ieee->dev;
- StaRateAdaptive87SE(dev);
-}
-void timer_rate_adaptive(unsigned long data)
-{
- struct r8180_priv *priv = ieee80211_priv((struct net_device *)data);
- if (!priv->up) {
- return;
- }
- if ((priv->ieee80211->iw_mode != IW_MODE_MASTER)
- && (priv->ieee80211->state == IEEE80211_LINKED) &&
- (priv->ForcedDataRate == 0)) {
- queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
- }
- priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
- add_timer(&priv->rateadapter_timer);
-}
-
-void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- priv->AdRxOkCnt++;
-
- if (priv->AdRxSignalStrength != -1) {
- priv->AdRxSignalStrength = ((priv->AdRxSignalStrength * 7) + (SignalStrength * 3)) / 10;
- } else { /* Initialization case. */
- priv->AdRxSignalStrength = SignalStrength;
- }
-
- if (priv->LastRxPktAntenna) /* Main antenna. */
- priv->AdMainAntennaRxOkCnt++;
- else /* Aux antenna. */
- priv->AdAuxAntennaRxOkCnt++;
-}
- /* Change Antenna Switch. */
-bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bAntennaSwitched = false;
-
- switch (u1bAntennaIndex) {
- case 0:
- /* Mac register, main antenna */
- write_nic_byte(dev, ANTSEL, 0x03);
- /* base band */
- write_phy_cck(dev, 0x11, 0x9b); /* Config CCK RX antenna. */
- write_phy_ofdm(dev, 0x0d, 0x5c); /* Config OFDM RX antenna. */
-
- bAntennaSwitched = true;
- break;
-
- case 1:
- /* Mac register, aux antenna */
- write_nic_byte(dev, ANTSEL, 0x00);
- /* base band */
- write_phy_cck(dev, 0x11, 0xbb); /* Config CCK RX antenna. */
- write_phy_ofdm(dev, 0x0d, 0x54); /* Config OFDM RX antenna. */
-
- bAntennaSwitched = true;
-
- break;
-
- default:
- printk("SetAntenna8185: unknown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
- break;
- }
-
- if (bAntennaSwitched)
- priv->CurrAntennaIndex = u1bAntennaIndex;
-
- return bAntennaSwitched;
-}
- /* Toggle Antenna switch. */
-bool SwitchAntenna(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- bool bResult;
-
- if (priv->CurrAntennaIndex == 0) {
- bResult = SetAntenna8185(dev, 1);
- } else {
- bResult = SetAntenna8185(dev, 0);
- }
-
- return bResult;
-}
-/*
- * Engine of SW Antenna Diversity mechanism.
- * Since 8187 has no Tx part information,
- * this implementation is only dependend on Rx part information.
- */
-void SwAntennaDiversity(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bSwCheckSS = false;
- if (bSwCheckSS) {
- priv->AdTickCount++;
-
- printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
- priv->AdTickCount, priv->AdCheckPeriod);
- printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
- priv->AdRxSignalStrength, priv->AdRxSsThreshold);
- }
-
- /* Case 1. No Link. */
- if (priv->ieee80211->state != IEEE80211_LINKED) {
- priv->bAdSwitchedChecking = false;
- /* I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko.. */
- SwitchAntenna(dev);
-
- /* Case 2. Linked but no packet receive.d */
- } else if (priv->AdRxOkCnt == 0) {
- priv->bAdSwitchedChecking = false;
- SwitchAntenna(dev);
-
- /* Case 3. Evaluate last antenna switch action and undo it if necessary. */
- } else if (priv->bAdSwitchedChecking == true) {
- priv->bAdSwitchedChecking = false;
-
- /* Adjust Rx signal strength threshold. */
- priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
-
- priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
- priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold;
- if (priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) {
- /* Rx signal strength is not improved after we swtiched antenna. => Swich back. */
- /* Increase Antenna Diversity checking period due to bad decision. */
- priv->AdCheckPeriod *= 2;
- /* Increase Antenna Diversity checking period. */
- if (priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
- priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
-
- /* Wrong decision => switch back. */
- SwitchAntenna(dev);
- } else {
- /* Rx Signal Strength is improved. */
-
- /* Reset Antenna Diversity checking period to its min value. */
- priv->AdCheckPeriod = priv->AdMinCheckPeriod;
- }
-
- }
- /* Case 4. Evaluate if we shall switch antenna now. */
- /* Cause Table Speed is very fast in TRC Dell Lab, we check it every time. */
- else {
- priv->AdTickCount = 0;
-
- /*
- * <Roger_Notes> We evaluate RxOk counts for each antenna first and than
- * evaluate signal strength.
- * The following operation can overcome the disability of CCA on both two antennas
- * When signal strength was extremely low or high.
- * 2008.01.30.
- */
-
- /*
- * Evaluate RxOk count from each antenna if we shall switch default antenna now.
- */
- if ((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt)
- && (priv->CurrAntennaIndex == 0)) {
- /* We set Main antenna as default but RxOk count was less than Aux ones. */
-
- /* Switch to Aux antenna. */
- SwitchAntenna(dev);
- priv->bHWAdSwitched = true;
- } else if ((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt)
- && (priv->CurrAntennaIndex == 1)) {
- /* We set Aux antenna as default but RxOk count was less than Main ones. */
-
- /* Switch to Main antenna. */
- SwitchAntenna(dev);
- priv->bHWAdSwitched = true;
- } else {
- /* Default antenna is better. */
-
- /* Still need to check current signal strength. */
- priv->bHWAdSwitched = false;
- }
- /*
- * <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
- * didn't change by HW evaluation.
- * 2008.02.27.
- *
- * [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
- * For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
- * but AdRxSignalStrength is less than main.
- * Our guess is that main antenna have lower throughput and get many change
- * to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
- */
- if ((!priv->bHWAdSwitched) && (bSwCheckSS)) {
- /* Evaluate Rx signal strength if we shall switch antenna now. */
- if (priv->AdRxSignalStrength < priv->AdRxSsThreshold) {
- /* Rx signal strength is weak => Switch Antenna. */
- priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
- priv->bAdSwitchedChecking = true;
-
- SwitchAntenna(dev);
- } else {
- /* Rx signal strength is OK. */
- priv->bAdSwitchedChecking = false;
- /* Increase Rx signal strength threshold if necessary. */
- if ((priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && /* Signal is much stronger than current threshold */
- priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) { /* Current threhold is not yet reach upper limit. */
-
- priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
- priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
- priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold;/* +by amy 080312 */
- }
-
- /* Reduce Antenna Diversity checking period if possible. */
- if (priv->AdCheckPeriod > priv->AdMinCheckPeriod)
- priv->AdCheckPeriod /= 2;
- }
- }
- }
- /* Reset antenna diversity Rx related statistics. */
- priv->AdRxOkCnt = 0;
- priv->AdMainAntennaRxOkCnt = 0;
- priv->AdAuxAntennaRxOkCnt = 0;
-}
-
- /* Return TRUE if we shall perform Tx Power Tracking Mechanism, FALSE otherwise. */
-bool CheckTxPwrTracking(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- if (!priv->bTxPowerTrack)
- return false;
-
- /* if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah */
- if (priv->bToUpdateTxPwr)
- return false;
-
- return true;
-}
-
-
- /* Timer callback function of SW Antenna Diversity. */
-void SwAntennaDiversityTimerCallback(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- enum rt_rf_power_state rtState;
-
- /* We do NOT need to switch antenna while RF is off. */
- rtState = priv->eRFPowerState;
- do {
- if (rtState == RF_OFF) {
- break;
- } else if (rtState == RF_SLEEP) {
- /* Don't access BB/RF under Disable PLL situation. */
- break;
- }
- SwAntennaDiversity(dev);
-
- } while (false);
-
- if (priv->up) {
- priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
- add_timer(&priv->SwAntennaDiversityTimer);
- }
-}
-
+++ /dev/null
-#ifndef R8180_DM_H
-#define R8180_DM_H
-
-#include "r8180.h"
-/* #include "r8180_hw.h" */
-/* #include "r8180_93cx6.h" */
-void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
-bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex);
-bool SwitchAntenna(struct net_device *dev);
-void SwAntennaDiversity(struct net_device *dev);
-void SwAntennaDiversityTimerCallback(struct net_device *dev);
-bool CheckDig(struct net_device *dev);
-bool CheckHighPower(struct net_device *dev);
-void rtl8180_hw_dig_wq(struct work_struct *work);
-void rtl8180_tx_pw_wq(struct work_struct *work);
-void rtl8180_rate_adapter(struct work_struct *work);
-void TxPwrTracking87SE(struct net_device *dev);
-bool CheckTxPwrTracking(struct net_device *dev);
-void rtl8180_rate_adapter(struct work_struct *work);
-void timer_rate_adaptive(unsigned long data);
-
-
-#endif
+++ /dev/null
-/*
- This is part of rtl8180 OpenSource driver.
- Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
- Released under the terms of GPL (General Public Licence)
-
- Parts of this driver are based on the GPL part of the
- official Realtek driver.
- Parts of this driver are based on the rtl8180 driver skeleton
- from Patric Schenke & Andres Salomon.
- Parts of this driver are based on the Intel Pro Wireless
- 2100 GPL driver.
-
- We want to tanks the Authors of those projects
- and the Ndiswrapper project Authors.
-*/
-
-/* Mariusz Matuszek added full registers definition with Realtek's name */
-
-/* this file contains register definitions for the rtl8180 MAC controller */
-#ifndef R8180_HW
-#define R8180_HW
-
-
-#define BIT0 0x00000001
-#define BIT1 0x00000002
-#define BIT2 0x00000004
-#define BIT3 0x00000008
-#define BIT4 0x00000010
-#define BIT5 0x00000020
-#define BIT6 0x00000040
-#define BIT7 0x00000080
-#define BIT9 0x00000200
-#define BIT11 0x00000800
-#define BIT13 0x00002000
-#define BIT15 0x00008000
-#define BIT20 0x00100000
-#define BIT21 0x00200000
-#define BIT22 0x00400000
-#define BIT23 0x00800000
-#define BIT24 0x01000000
-#define BIT25 0x02000000
-#define BIT26 0x04000000
-#define BIT27 0x08000000
-#define BIT28 0x10000000
-#define BIT29 0x20000000
-#define BIT30 0x40000000
-#define BIT31 0x80000000
-
-#define MAX_SLEEP_TIME (10000)
-#define MIN_SLEEP_TIME (50)
-
-#define BB_HOST_BANG_EN (1<<2)
-#define BB_HOST_BANG_CLK (1<<1)
-
-#define MAC0 0
-#define MAC4 4
-
-#define CMD 0x37
-#define CMD_RST_SHIFT 4
-#define CMD_RX_ENABLE_SHIFT 3
-#define CMD_TX_ENABLE_SHIFT 2
-
-#define EPROM_CMD 0x50
-#define EPROM_CMD_RESERVED_MASK ((1<<5)|(1<<4))
-#define EPROM_CMD_OPERATING_MODE_SHIFT 6
-#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
-#define EPROM_CMD_CONFIG 0x3
-#define EPROM_CMD_NORMAL 0
-#define EPROM_CMD_LOAD 1
-#define EPROM_CMD_PROGRAM 2
-#define EPROM_CS_SHIFT 3
-#define EPROM_CK_SHIFT 2
-#define EPROM_W_SHIFT 1
-#define EPROM_R_SHIFT 0
-#define CONFIG2_DMA_POLLING_MODE_SHIFT 3
-
-#define INTA_TXOVERFLOW (1<<15)
-#define INTA_TIMEOUT (1<<14)
-#define INTA_HIPRIORITYDESCERR (1<<9)
-#define INTA_HIPRIORITYDESCOK (1<<8)
-#define INTA_NORMPRIORITYDESCERR (1<<7)
-#define INTA_NORMPRIORITYDESCOK (1<<6)
-#define INTA_RXOVERFLOW (1<<5)
-#define INTA_RXDESCERR (1<<4)
-#define INTA_LOWPRIORITYDESCERR (1<<3)
-#define INTA_LOWPRIORITYDESCOK (1<<2)
-#define INTA_RXOK (1)
-#define INTA_MASK 0x3c
-
-#define RXRING_ADDR 0xe4 /* page 0 */
-#define PGSELECT 0x5e
-#define PGSELECT_PG_SHIFT 0
-#define RX_CONF 0x44
-#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
-(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
-#define RX_CHECK_BSSID_SHIFT 23
-#define ACCEPT_PWR_FRAME_SHIFT 22
-#define ACCEPT_MNG_FRAME_SHIFT 20
-#define ACCEPT_CTL_FRAME_SHIFT 19
-#define ACCEPT_DATA_FRAME_SHIFT 18
-#define ACCEPT_ICVERR_FRAME_SHIFT 12
-#define ACCEPT_CRCERR_FRAME_SHIFT 5
-#define ACCEPT_BCAST_FRAME_SHIFT 3
-#define ACCEPT_MCAST_FRAME_SHIFT 2
-#define ACCEPT_ALLMAC_FRAME_SHIFT 0
-#define ACCEPT_NICMAC_FRAME_SHIFT 1
-
-#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
-#define RX_FIFO_THRESHOLD_SHIFT 13
-#define RX_FIFO_THRESHOLD_NONE 7
-#define RX_AUTORESETPHY_SHIFT 28
-
-#define TX_CONF 0x40
-#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30
-#define TX_LOOPBACK_SHIFT 17
-#define TX_LOOPBACK_NONE 0
-#define TX_LOOPBACK_CONTINUE 3
-#define TX_LOOPBACK_MASK ((1<<17)|(1<<18))
-#define TX_DPRETRY_SHIFT 0
-#define R8180_MAX_RETRY 255
-#define TX_RTSRETRY_SHIFT 8
-#define TX_NOICV_SHIFT 19
-#define TX_NOCRC_SHIFT 16
-#define TX_DMA_POLLING 0xd9
-#define TX_DMA_POLLING_BEACON_SHIFT 7
-#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6
-#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5
-#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4
-#define TX_MANAGEPRIORITY_RING_ADDR 0x0C
-#define TX_BKPRIORITY_RING_ADDR 0x10
-#define TX_BEPRIORITY_RING_ADDR 0x14
-#define TX_VIPRIORITY_RING_ADDR 0x20
-#define TX_VOPRIORITY_RING_ADDR 0x24
-#define TX_HIGHPRIORITY_RING_ADDR 0x28
-#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
-#define MAX_RX_DMA_2048 7
-#define MAX_RX_DMA_1024 6
-#define MAX_RX_DMA_SHIFT 10
-#define INT_TIMEOUT 0x48
-#define CONFIG3_CLKRUN_SHIFT 2
-#define CONFIG3_ANAPARAM_W_SHIFT 6
-#define ANAPARAM 0x54
-#define BEACON_INTERVAL 0x70
-#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \
-(1<<6)|(1<<7)|(1<<8)|(1<<9))
-#define ATIM_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)| \
-(1<<8)|(1<<9))
-#define ATIM 0x72
-#define EPROM_CS_SHIFT 3
-#define EPROM_CK_SHIFT 2
-#define PHY_ADR 0x7c
-#define SECURITY 0x5f /* 1209 this is sth wrong */
-#define SECURITY_WEP_TX_ENABLE_SHIFT 1
-#define SECURITY_WEP_RX_ENABLE_SHIFT 0
-#define SECURITY_ENCRYP_104 1
-#define SECURITY_ENCRYP_SHIFT 4
-#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5))
-#define KEY0 0x90 /* 1209 this is sth wrong */
-#define CONFIG2_ANTENNA_SHIFT 6
-#define TX_BEACON_RING_ADDR 0x4c
-#define CONFIG0_WEP40_SHIFT 7
-#define CONFIG0_WEP104_SHIFT 6
-#define AGCRESET_SHIFT 5
-
-
-
-/*
- * Operational registers offsets in PCI (I/O) space.
- * RealTek names are used.
- */
-
-#define TSFTR 0x0018
-
-#define TLPDA 0x0020
-
-#define BSSID 0x002E
-
-#define CR 0x0037
-
-#define RF_SW_CONFIG 0x8 /* store data which is transmitted to RF for driver */
-#define RF_SW_CFG_SI BIT1
-#define EIFS 0x2D /* Extended InterFrame Space Timer, in unit of 4 us. */
-
-#define BRSR 0x34 /* Basic rate set */
-
-#define IMR 0x006C
-#define ISR 0x003C
-
-#define TCR 0x0040
-
-#define RCR 0x0044
-
-#define TimerInt 0x0048
-
-#define CR9346 0x0050
-
-#define CONFIG0 0x0051
-#define CONFIG2 0x0053
-
-#define MSR 0x0058
-
-#define CONFIG3 0x0059
-#define CONFIG4 0x005A
- /* SD3 szuyitasi: Mac0x57= CC -> B0 Mac0x60= D1 -> C6 */
- /* Mac0x60 = 0x000004C6 power save parameters */
- #define ANAPARM_ASIC_ON 0xB0054D00
- #define ANAPARM2_ASIC_ON 0x000004C6
-
- #define ANAPARM_ON ANAPARM_ASIC_ON
- #define ANAPARM2_ON ANAPARM2_ASIC_ON
-
-#define TESTR 0x005B
-
-#define PSR 0x005E
-
-#define BcnItv 0x0070
-
-#define AtimWnd 0x0072
-
-#define BintrItv 0x0074
-
-#define PhyAddr 0x007C
-#define PhyDataR 0x007E
-
-/* following are for rtl8185 */
-#define RFPinsOutput 0x80
-#define RFPinsEnable 0x82
-#define RF_TIMING 0x8c
-#define RFPinsSelect 0x84
-#define ANAPARAM2 0x60
-#define RF_PARA 0x88
-#define RFPinsInput 0x86
-#define GP_ENABLE 0x90
-#define GPIO 0x91
-#define SW_CONTROL_GPIO 0x400
-#define TX_ANTENNA 0x9f
-#define TX_GAIN_OFDM 0x9e
-#define TX_GAIN_CCK 0x9d
-#define WPA_CONFIG 0xb0
-#define TX_AGC_CTL 0x9c
-#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0
-#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1
-#define TX_AGC_CTL_FEEDBACK_ANT 2
-#define RESP_RATE 0x34
-#define SIFS 0xb4
-#define DIFS 0xb5
-
-#define SLOT 0xb6
-#define CW_CONF 0xbc
-#define CW_CONF_PERPACKET_RETRY_SHIFT 1
-#define CW_CONF_PERPACKET_CW_SHIFT 0
-#define CW_VAL 0xbd
-#define MAX_RESP_RATE_SHIFT 4
-#define MIN_RESP_RATE_SHIFT 0
-#define RATE_FALLBACK 0xbe
-
-#define CONFIG5 0x00D8
-
-#define PHYPR 0xDA /* 0xDA - 0x0B PHY Parameter Register. */
-
-#define FEMR 0x1D4 /* Function Event Mask register */
-
-#define FFER 0x00FC
-#define FFER_END 0x00FF
-
-
-
-/*
- * Bitmasks for specific register functions.
- * Names are derived from the register name and function name.
- *
- * <REGISTER>_<FUNCTION>[<bit>]
- *
- * this leads to some awkward names...
- */
-
-#define BRSR_BPLCP ((1 << 8))
-#define BRSR_MBR ((1 << 1)|(1 << 0))
-#define BRSR_MBR_8185 ((1 << 11)|(1 << 10)|(1 << 9)|(1 << 8)|(1 << 7)|(1 << 6)|(1 << 5)|(1 << 4)|(1 << 3)|(1 << 2)|(1 << 1)|(1 << 0))
-#define BRSR_MBR0 ((1 << 0))
-#define BRSR_MBR1 ((1 << 1))
-
-#define CR_RST ((1 << 4))
-#define CR_RE ((1 << 3))
-#define CR_TE ((1 << 2))
-#define CR_MulRW ((1 << 0))
-
-#define IMR_Dot11hInt ((1 << 25)) /*802.11h Measurement Interrupt */
-#define IMR_BcnDmaInt ((1 << 24)) /*Beacon DMA Interrupt */ /*What differenct between BcnDmaInt and BcnInt??? */
-#define IMR_WakeInt ((1 << 23)) /*Wake Up Interrupt */
-#define IMR_TXFOVW ((1 << 22)) /*Tx FIFO Overflow Interrupt */
-#define IMR_TimeOut1 ((1 << 21)) /*Time Out Interrupt 1 */
-#define IMR_BcnInt ((1 << 20)) /*Beacon Time out Interrupt */
-#define IMR_ATIMInt ((1 << 19)) /*ATIM Time Out Interrupt */
-#define IMR_TBDER ((1 << 18)) /*Tx Beacon Descriptor Error Interrupt */
-#define IMR_TBDOK ((1 << 17)) /*Tx Beacon Descriptor OK Interrupt */
-#define IMR_THPDER ((1 << 16)) /*Tx High Priority Descriptor Error Interrupt */
-#define IMR_THPDOK ((1 << 15)) /*Tx High Priority Descriptor OK Interrupt */
-#define IMR_TVODER ((1 << 14)) /*Tx AC_VO Descriptor Error Interrupt */
-#define IMR_TVODOK ((1 << 13)) /*Tx AC_VO Descriptor OK Interrupt */
-#define IMR_FOVW ((1 << 12)) /*Rx FIFO Overflow Interrupt */
-#define IMR_RDU ((1 << 11)) /*Rx Descriptor Unavailable Interrupt */
-#define IMR_TVIDER ((1 << 10)) /*Tx AC_VI Descriptor Error Interrupt */
-#define IMR_TVIDOK ((1 << 9)) /*Tx AC_VI Descriptor OK Interrupt */
-#define IMR_RER ((1 << 8)) /*Rx Error Interrupt */
-#define IMR_ROK ((1 << 7)) /*Receive OK Interrupt */
-#define IMR_TBEDER ((1 << 6)) /*Tx AC_BE Descriptor Error Interrupt */
-#define IMR_TBEDOK ((1 << 5)) /*Tx AC_BE Descriptor OK Interrupt */
-#define IMR_TBKDER ((1 << 4)) /*Tx AC_BK Descriptor Error Interrupt */
-#define IMR_TBKDOK ((1 << 3)) /*Tx AC_BK Descriptor OK Interrupt */
-#define IMR_RQoSOK ((1 << 2)) /*Rx QoS OK Interrupt */
-#define IMR_TimeOut2 ((1 << 1)) /*Time Out Interrupt 2 */
-#define IMR_TimeOut3 ((1 << 0)) /*Time Out Interrupt 3 */
-#define IMR_TMGDOK ((1 << 30))
-#define ISR_Dot11hInt ((1 << 25)) /*802.11h Measurement Interrupt */
-#define ISR_BcnDmaInt ((1 << 24)) /*Beacon DMA Interrupt */ /*What differenct between BcnDmaInt and BcnInt??? */
-#define ISR_WakeInt ((1 << 23)) /*Wake Up Interrupt */
-#define ISR_TXFOVW ((1 << 22)) /*Tx FIFO Overflow Interrupt */
-#define ISR_TimeOut1 ((1 << 21)) /*Time Out Interrupt 1 */
-#define ISR_BcnInt ((1 << 20)) /*Beacon Time out Interrupt */
-#define ISR_ATIMInt ((1 << 19)) /*ATIM Time Out Interrupt */
-#define ISR_TBDER ((1 << 18)) /*Tx Beacon Descriptor Error Interrupt */
-#define ISR_TBDOK ((1 << 17)) /*Tx Beacon Descriptor OK Interrupt */
-#define ISR_THPDER ((1 << 16)) /*Tx High Priority Descriptor Error Interrupt */
-#define ISR_THPDOK ((1 << 15)) /*Tx High Priority Descriptor OK Interrupt */
-#define ISR_TVODER ((1 << 14)) /*Tx AC_VO Descriptor Error Interrupt */
-#define ISR_TVODOK ((1 << 13)) /*Tx AC_VO Descriptor OK Interrupt */
-#define ISR_FOVW ((1 << 12)) /*Rx FIFO Overflow Interrupt */
-#define ISR_RDU ((1 << 11)) /*Rx Descriptor Unavailable Interrupt */
-#define ISR_TVIDER ((1 << 10)) /*Tx AC_VI Descriptor Error Interrupt */
-#define ISR_TVIDOK ((1 << 9)) /*Tx AC_VI Descriptor OK Interrupt */
-#define ISR_RER ((1 << 8)) /*Rx Error Interrupt */
-#define ISR_ROK ((1 << 7)) /*Receive OK Interrupt */
-#define ISR_TBEDER ((1 << 6)) /*Tx AC_BE Descriptor Error Interrupt */
-#define ISR_TBEDOK ((1 << 5)) /*Tx AC_BE Descriptor OK Interrupt */
-#define ISR_TBKDER ((1 << 4)) /*Tx AC_BK Descriptor Error Interrupt */
-#define ISR_TBKDOK ((1 << 3)) /*Tx AC_BK Descriptor OK Interrupt */
-#define ISR_RQoSOK ((1 << 2)) /*Rx QoS OK Interrupt */
-#define ISR_TimeOut2 ((1 << 1)) /*Time Out Interrupt 2 */
-#define ISR_TimeOut3 ((1 << 0)) /*Time Out Interrupt 3 */
-
-/* these definition is used for Tx/Rx test temporarily */
-#define ISR_TLPDER ISR_TVIDER
-#define ISR_TLPDOK ISR_TVIDOK
-#define ISR_TNPDER ISR_TVODER
-#define ISR_TNPDOK ISR_TVODOK
-#define ISR_TimeOut ISR_TimeOut1
-#define ISR_RXFOVW ISR_FOVW
-
-
-#define HW_VERID_R8180_F 3
-#define HW_VERID_R8180_ABCD 2
-#define HW_VERID_R8185_ABC 4
-#define HW_VERID_R8185_D 5
-#define HW_VERID_R8185B_B 6
-
-#define TCR_CWMIN ((1 << 31))
-#define TCR_SWSEQ ((1 << 30))
-#define TCR_HWVERID_MASK ((1 << 27)|(1 << 26)|(1 << 25))
-#define TCR_HWVERID_SHIFT 25
-#define TCR_SAT ((1 << 24))
-#define TCR_PLCP_LEN TCR_SAT /* rtl8180 */
-#define TCR_MXDMA_MASK ((1 << 23)|(1 << 22)|(1 << 21))
-#define TCR_MXDMA_1024 6
-#define TCR_MXDMA_2048 7
-#define TCR_MXDMA_SHIFT 21
-#define TCR_DISCW ((1 << 20))
-#define TCR_ICV ((1 << 19))
-#define TCR_LBK ((1 << 18)|(1 << 17))
-#define TCR_LBK1 ((1 << 18))
-#define TCR_LBK0 ((1 << 17))
-#define TCR_CRC ((1 << 16))
-#define TCR_DPRETRY_MASK ((1 << 15)|(1 << 14)|(1 << 13)|(1 << 12)|(1 << 11)|(1 << 10)|(1 << 9)|(1 << 8))
-#define TCR_RTSRETRY_MASK ((1 << 0)|(1 << 1)|(1 << 2)|(1 << 3)|(1 << 4)|(1 << 5)|(1 << 6)|(1 << 7))
-#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 /* rtl8185 */
-
-#define RCR_ONLYERLPKT ((1 << 31))
-#define RCR_CS_SHIFT 29
-#define RCR_CS_MASK ((1 << 30) | (1 << 29))
-#define RCR_ENMARP ((1 << 28))
-#define RCR_CBSSID ((1 << 23))
-#define RCR_APWRMGT ((1 << 22))
-#define RCR_ADD3 ((1 << 21))
-#define RCR_AMF ((1 << 20))
-#define RCR_ACF ((1 << 19))
-#define RCR_ADF ((1 << 18))
-#define RCR_RXFTH ((1 << 15)|(1 << 14)|(1 << 13))
-#define RCR_RXFTH2 ((1 << 15))
-#define RCR_RXFTH1 ((1 << 14))
-#define RCR_RXFTH0 ((1 << 13))
-#define RCR_AICV ((1 << 12))
-#define RCR_MXDMA ((1 << 10)|(1 << 9)|(1 << 8))
-#define RCR_MXDMA2 ((1 << 10))
-#define RCR_MXDMA1 ((1 << 9))
-#define RCR_MXDMA0 ((1 << 8))
-#define RCR_9356SEL ((1 << 6))
-#define RCR_ACRC32 ((1 << 5))
-#define RCR_AB ((1 << 3))
-#define RCR_AM ((1 << 2))
-#define RCR_APM ((1 << 1))
-#define RCR_AAP ((1 << 0))
-
-#define CR9346_EEM ((1 << 7)|(1 << 6))
-#define CR9346_EEM1 ((1 << 7))
-#define CR9346_EEM0 ((1 << 6))
-#define CR9346_EECS ((1 << 3))
-#define CR9346_EESK ((1 << 2))
-#define CR9346_EED1 ((1 << 1))
-#define CR9346_EED0 ((1 << 0))
-
-#define CONFIG3_PARM_En ((1 << 6))
-#define CONFIG3_FuncRegEn ((1 << 1))
-
-#define CONFIG4_PWRMGT ((1 << 5))
-
-#define MSR_LINK_MASK ((1 << 2)|(1 << 3))
-#define MSR_LINK_MANAGED 2
-#define MSR_LINK_NONE 0
-#define MSR_LINK_SHIFT 2
-#define MSR_LINK_ADHOC 1
-#define MSR_LINK_MASTER 3
-
-#define BcnItv_BcnItv (0x01FF)
-
-#define AtimWnd_AtimWnd (0x01FF)
-
-#define BintrItv_BintrItv (0x01FF)
-
-#define FEMR_INTR ((1 << 15))
-#define FEMR_WKUP ((1 << 14))
-#define FEMR_GWAKE ((1 << 4))
-
-#define FFER_INTR ((1 << 15))
-#define FFER_GWAKE ((1 << 4))
-
-/* Three wire mode. */
-#define SW_THREE_WIRE 0
-#define HW_THREE_WIRE 2
-/* RTL8187S by amy */
-#define HW_THREE_WIRE_PI 5
-#define HW_THREE_WIRE_SI 6
-/* by amy */
-#define TCR_LRL_OFFSET 0
-#define TCR_SRL_OFFSET 8
-#define TCR_MXDMA_OFFSET 21
-#define TCR_DISReqQsize_OFFSET 28
-#define TCR_DurProcMode_OFFSET 30
-
-#define RCR_MXDMA_OFFSET 8
-#define RCR_FIFO_OFFSET 13
-
-#define AckTimeOutReg 0x79 /* ACK timeout register, in unit of 4 us. */
-
-#define RFTiming 0x8C
-
-#define TPPollStop 0x93
-
-#define TXAGC_CTL 0x9C /*< RJ_TODO_8185B> TX_AGC_CONTROL (0x9C seems be removed at 8185B, see p37). */
-#define CCK_TXAGC 0x9D
-#define OFDM_TXAGC 0x9E
-#define ANTSEL 0x9F
-
-#define ACM_CONTROL 0x00BF /* ACM Control Registe */
-
-#define IntMig 0xE2 /* Interrupt Migration (0xE2 ~ 0xE3) */
-
-#define TID_AC_MAP 0xE8 /* TID to AC Mapping Register */
-
-#define ANAPARAM3 0xEE /* <RJ_TODO_8185B> How to use it? */
-
-#define AC_VO_PARAM 0xF0 /* AC_VO Parameters Record */
-#define AC_VI_PARAM 0xF4 /* AC_VI Parameters Record */
-#define AC_BE_PARAM 0xF8 /* AC_BE Parameters Record */
-#define AC_BK_PARAM 0xFC /* AC_BK Parameters Record */
-
-#define GPIOCtrl 0x16B /*GPIO Control Register. */
-#define ARFR 0x1E0 /* Auto Rate Fallback Register (0x1e0 ~ 0x1e2) */
-
-#define RFSW_CTRL 0x272 /* 0x272-0x273. */
-#define SW_3W_DB0 0x274 /* Software 3-wire data buffer bit 31~0. */
-#define SW_3W_DB1 0x278 /* Software 3-wire data buffer bit 63~32. */
-#define SW_3W_CMD0 0x27C /* Software 3-wire Control/Status Register. */
-#define SW_3W_CMD1 0x27D /* Software 3-wire Control/Status Register. */
-
-#define PI_DATA_READ 0X360 /* 0x360 - 0x361 Parallel Interface Data Register. */
-#define SI_DATA_READ 0x362 /* 0x362 - 0x363 Serial Interface Data Register. */
-
-/*
-----------------------------------------------------------------------------
- 8185B TPPollStop bits (offset 0x93, 1 byte)
-----------------------------------------------------------------------------
-*/
-#define TPPOLLSTOP_BQ (0x01 << 7)
-#define TPPOLLSTOP_AC_VIQ (0x01 << 4)
-
-#define MSR_LINK_ENEDCA (1<<4)
-
-/*
-----------------------------------------------------------------------------
- 8187B AC_XX_PARAM bits
-----------------------------------------------------------------------------
-*/
-#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
-
-/*
-----------------------------------------------------------------------------
- 8187B ACM_CONTROL bits (Offset 0xBF, 1 Byte)
-----------------------------------------------------------------------------
-*/
-#define VOQ_ACM_EN (0x01 << 7) /*BIT7 */
-#define VIQ_ACM_EN (0x01 << 6) /*BIT6 */
-#define BEQ_ACM_EN (0x01 << 5) /*BIT5 */
-#define ACM_HW_EN (0x01 << 4) /*BIT4 */
-#define VOQ_ACM_CTL (0x01 << 2) /*BIT2 */ /* Set to 1 when AC_VO used time reaches or exceeds the admitted time */
-#define VIQ_ACM_CTL (0x01 << 1) /*BIT1 */ /* Set to 1 when AC_VI used time reaches or exceeds the admitted time */
-#define BEQ_ACM_CTL (0x01 << 0) /*BIT0 */ /* Set to 1 when AC_BE used time reaches or exceeds the admitted time */
-
-
-/*
-----------------------------------------------------------------------------
- 8185B SW_3W_CMD bits (Offset 0x27C-0x27D, 16bit)
-----------------------------------------------------------------------------
-*/
-#define SW_3W_CMD0_HOLD ((1 << 7))
-#define SW_3W_CMD1_RE ((1 << 0)) /* BIT8 */
-#define SW_3W_CMD1_WE ((1 << 1)) /* BIT9 */
-#define SW_3W_CMD1_DONE ((1 << 2)) /* BIT10 */
-
-#define BB_HOST_BANG_RW (1 << 3)
-
-/*
-----------------------------------------------------------------------------
- 8185B RATE_FALLBACK_CTL bits (Offset 0xBE, 8bit)
-----------------------------------------------------------------------------
-*/
-#define RATE_FALLBACK_CTL_ENABLE ((1 << 7))
-#define RATE_FALLBACK_CTL_ENABLE_RTSCTS ((1 << 6))
-/* Auto rate fallback per 2^n retry. */
-#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00
-#define RATE_FALLBACK_CTL_AUTO_STEP1 0x01
-#define RATE_FALLBACK_CTL_AUTO_STEP2 0x02
-#define RATE_FALLBACK_CTL_AUTO_STEP3 0x03
-
-
-#define RTL8225z2_ANAPARAM_OFF 0x55480658
-#define RTL8225z2_ANAPARAM2_OFF 0x72003f70
-/* by amy for power save */
-#define RF_CHANGE_BY_HW BIT30
-#define RF_CHANGE_BY_PS BIT29
-#define RF_CHANGE_BY_IPS BIT28
-/* by amy for power save */
-/* by amy for antenna */
-#define EEPROM_SW_REVD_OFFSET 0x3f
-
-/* BIT[8-9] is for SW Antenna Diversity.
- * Only the value EEPROM_SW_AD_ENABLE means enable, other values are disable.
- */
-#define EEPROM_SW_AD_MASK 0x0300
-#define EEPROM_SW_AD_ENABLE 0x0100
-
-/* BIT[10-11] determine if Antenna 1 is the Default Antenna.
- * Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE.
- */
-#define EEPROM_DEF_ANT_MASK 0x0C00
-#define EEPROM_DEF_ANT_1 0x0400
-/*by amy for antenna */
-/* {by amy 080312 */
-/* 0x7C, 0x7D Crystal calibration and Tx Power tracking mechanism. Added by Roger. 2007.12.10. */
-#define EEPROM_RSV 0x7C
-#define EEPROM_XTAL_CAL_XOUT_MASK 0x0F /* 0x7C[3:0], Crystal calibration for Xout. */
-#define EEPROM_XTAL_CAL_XIN_MASK 0xF0 /* 0x7C[7:4], Crystal calibration for Xin. */
-#define EEPROM_THERMAL_METER_MASK 0x0F00 /* 0x7D[3:0], Thermal meter reference level. */
-#define EEPROM_XTAL_CAL_ENABLE 0x1000 /* 0x7D[4], Crystal calibration enabled/disabled BIT. */
-#define EEPROM_THERMAL_METER_ENABLE 0x2000 /* 0x7D[5], Thermal meter enabled/disabled BIT. */
-#define EN_LPF_CAL 0x238 /* Enable LPF Calibration. */
-#define PWR_METER_EN BIT1
-/* <RJ_TODO_8185B> where are false alarm counters in 8185B? */
-#define CCK_FALSE_ALARM 0xD0
-/* by amy 080312} */
-
-/* YJ,add for Country IE, 080630 */
-#define EEPROM_COUNTRY_CODE 0x2E
-/* YJ,add,080630,end */
-
-#endif
+++ /dev/null
-/*
- * This is part of the rtl8180-sa2400 driver released under the GPL (See file
- * COPYING for details).
- *
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * This files contains programming code for the rtl8225 radio frontend.
- *
- * *Many* thanks to Realtek Corp. for their great support!
- */
-
-#include "r8180.h"
-
-#define RTL8225_ANAPARAM_ON 0xa0000b59
-#define RTL8225_ANAPARAM_OFF 0xa00beb59
-#define RTL8225_ANAPARAM2_OFF 0x840dec11
-#define RTL8225_ANAPARAM2_ON 0x860dec11
-#define RTL8225_ANAPARAM_SLEEP 0xa00bab59
-#define RTL8225_ANAPARAM2_SLEEP 0x840dec11
-
-void rtl8225z2_rf_init(struct net_device *dev);
-void rtl8225z2_rf_set_chan(struct net_device *dev, short ch);
-void rtl8225z2_rf_close(struct net_device *dev);
-
-void RF_WriteReg(struct net_device *dev, u8 offset, u16 data);
-u16 RF_ReadReg(struct net_device *dev, u8 offset);
-
-void rtl8180_set_mode(struct net_device *dev, int mode);
-void rtl8180_set_mode(struct net_device *dev, int mode);
-bool SetZebraRFPowerState8185(struct net_device *dev,
- enum rt_rf_power_state eRFPowerState);
-void rtl8225z4_rf_sleep(struct net_device *dev);
-void rtl8225z4_rf_wakeup(struct net_device *dev);
-
+++ /dev/null
-/*
- * This is part of the rtl8180-sa2400 driver
- * released under the GPL (See file COPYING for details).
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * This files contains programming code for the rtl8225
- * radio frontend.
- *
- * *Many* thanks to Realtek Corp. for their great support!
- */
-
-#include "r8180_hw.h"
-#include "r8180_rtl8225.h"
-#include "r8180_93cx6.h"
-
-#include "ieee80211/dot11d.h"
-
-static void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
-{
- int i;
- u16 out, select;
- u8 bit;
- u32 bangdata = (data << 4) | (adr & 0xf);
-
- out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
-
- write_nic_word(dev, RFPinsEnable,
- (read_nic_word(dev, RFPinsEnable) | 0x7));
-
- select = read_nic_word(dev, RFPinsSelect);
-
- write_nic_word(dev, RFPinsSelect, select | 0x7 |
- SW_CONTROL_GPIO);
-
- force_pci_posting(dev);
- udelay(10);
-
- write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-
- force_pci_posting(dev);
- udelay(2);
-
- write_nic_word(dev, RFPinsOutput, out);
-
- force_pci_posting(dev);
- udelay(10);
-
- for (i = 15; i >= 0; i--) {
- bit = (bangdata & (1 << i)) >> i;
-
- write_nic_word(dev, RFPinsOutput, bit | out);
-
- write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
- write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-
- i--;
- bit = (bangdata & (1 << i)) >> i;
-
- write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
- write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-
- write_nic_word(dev, RFPinsOutput, bit | out);
-
- }
-
- write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-
- force_pci_posting(dev);
- udelay(10);
-
- write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-
- write_nic_word(dev, RFPinsSelect, select | SW_CONTROL_GPIO);
-
- rtl8185_rf_pins_enable(dev);
-}
-
-static const u8 rtl8225_agc[] = {
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
- 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
- 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
- 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
- 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
- 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
- 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
- 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
- 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
- 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
- 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
- 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-};
-
-static const u32 rtl8225_chan[] = {
- 0,
- 0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380,
- 0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x074A,
-};
-
-static const u8 rtl8225z2_gain_bg[] = {
- 0x23, 0x15, 0xa5, /* -82-1dBm */
- 0x23, 0x15, 0xb5, /* -82-2dBm */
- 0x23, 0x15, 0xc5, /* -82-3dBm */
- 0x33, 0x15, 0xc5, /* -78dBm */
- 0x43, 0x15, 0xc5, /* -74dBm */
- 0x53, 0x15, 0xc5, /* -70dBm */
- 0x63, 0x15, 0xc5, /* -66dBm */
-};
-
-static const u8 rtl8225z2_gain_a[] = {
- 0x13, 0x27, 0x5a, /* -82dBm */
- 0x23, 0x23, 0x58, /* -82dBm */
- 0x33, 0x1f, 0x56, /* -82dBm */
- 0x43, 0x1b, 0x54, /* -78dBm */
- 0x53, 0x17, 0x51, /* -74dBm */
- 0x63, 0x24, 0x4f, /* -70dBm */
- 0x73, 0x0f, 0x4c, /* -66dBm */
-};
-
-static const u16 rtl8225z2_rxgain[] = {
- 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
- 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
- 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
- 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
- 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
- 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
- 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
- 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
- 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
- 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
- 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
- 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb
-
-};
-
-static void rtl8225z2_set_gain(struct net_device *dev, short gain)
-{
- const u8 *rtl8225_gain;
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 mode = priv->ieee80211->mode;
-
- if (mode == IEEE_B || mode == IEEE_G)
- rtl8225_gain = rtl8225z2_gain_bg;
- else
- rtl8225_gain = rtl8225z2_gain_a;
-
- write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]);
- write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]);
- write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]);
- write_phy_ofdm(dev, 0x21, 0x37);
-}
-
-static u32 read_rtl8225(struct net_device *dev, u8 adr)
-{
- u32 data2Write = ((u32)(adr & 0x1f)) << 27;
- u32 dataRead;
- u32 mask;
- u16 oval, oval2, oval3, tmp;
- int i;
- short bit, rw;
- u8 wLength = 6;
- u8 rLength = 12;
- u8 low2high = 0;
-
- oval = read_nic_word(dev, RFPinsOutput);
- oval2 = read_nic_word(dev, RFPinsEnable);
- oval3 = read_nic_word(dev, RFPinsSelect);
-
- write_nic_word(dev, RFPinsEnable, (oval2|0xf));
- write_nic_word(dev, RFPinsSelect, (oval3|0xf));
-
- dataRead = 0;
-
- oval &= ~0xf;
-
- write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN);
- udelay(4);
-
- write_nic_word(dev, RFPinsOutput, oval);
- udelay(5);
-
- rw = 0;
-
- mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1));
-
- for (i = 0; i < wLength/2; i++) {
- bit = ((data2Write&mask) != 0) ? 1 : 0;
- write_nic_word(dev, RFPinsOutput, bit | oval | rw);
- udelay(1);
-
- write_nic_word(dev, RFPinsOutput,
- bit | oval | BB_HOST_BANG_CLK | rw);
- udelay(2);
- write_nic_word(dev, RFPinsOutput,
- bit | oval | BB_HOST_BANG_CLK | rw);
- udelay(2);
-
- mask = (low2high) ? (mask<<1) : (mask>>1);
-
- if (i == 2) {
- rw = BB_HOST_BANG_RW;
- write_nic_word(dev, RFPinsOutput,
- bit | oval | BB_HOST_BANG_CLK | rw);
- udelay(2);
- write_nic_word(dev, RFPinsOutput, bit | oval | rw);
- udelay(2);
- break;
- }
-
- bit = ((data2Write&mask) != 0) ? 1 : 0;
-
- write_nic_word(dev, RFPinsOutput,
- oval | bit | rw | BB_HOST_BANG_CLK);
- udelay(2);
- write_nic_word(dev, RFPinsOutput,
- oval | bit | rw | BB_HOST_BANG_CLK);
- udelay(2);
-
- write_nic_word(dev, RFPinsOutput, oval | bit | rw);
- udelay(1);
-
- mask = (low2high) ? (mask<<1) : (mask>>1);
- }
-
- write_nic_word(dev, RFPinsOutput, rw|oval);
- udelay(2);
- mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1));
-
- /*
- * We must set data pin to HW controlled, otherwise RF can't driver it
- * and value RF register won't be able to read back properly.
- */
- write_nic_word(dev, RFPinsEnable, (oval2 & (~0x01)));
-
- for (i = 0; i < rLength; i++) {
- write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1);
-
- write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK);
- udelay(2);
- write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK);
- udelay(2);
- write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK);
- udelay(2);
- tmp = read_nic_word(dev, RFPinsInput);
-
- dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0);
-
- write_nic_word(dev, RFPinsOutput, (rw|oval)); udelay(2);
-
- mask = (low2high) ? (mask<<1) : (mask>>1);
- }
-
- write_nic_word(dev, RFPinsOutput,
- BB_HOST_BANG_EN | BB_HOST_BANG_RW | oval);
- udelay(2);
-
- write_nic_word(dev, RFPinsEnable, oval2);
- write_nic_word(dev, RFPinsSelect, oval3); /* Set To SW Switch */
- write_nic_word(dev, RFPinsOutput, 0x3a0);
-
- return dataRead;
-}
-
-void rtl8225z2_rf_close(struct net_device *dev)
-{
- RF_WriteReg(dev, 0x4, 0x1f);
-
- force_pci_posting(dev);
- mdelay(1);
-
- rtl8180_set_anaparam(dev, RTL8225z2_ANAPARAM_OFF);
- rtl8185_set_anaparam2(dev, RTL8225z2_ANAPARAM2_OFF);
-}
-
-/*
- * Map dBm into Tx power index according to current HW model, for example,
- * RF and PA, and current wireless mode.
- */
-static s8 DbmToTxPwrIdx(struct r8180_priv *priv,
- enum wireless_mode mode, s32 PowerInDbm)
-{
- bool bUseDefault = true;
- s8 TxPwrIdx = 0;
-
- /*
- * OFDM Power in dBm = Index * 0.5 + 0
- * CCK Power in dBm = Index * 0.25 + 13
- */
- s32 tmp = 0;
-
- if (mode == WIRELESS_MODE_G) {
- bUseDefault = false;
- tmp = (2 * PowerInDbm);
-
- if (tmp < 0)
- TxPwrIdx = 0;
- else if (tmp > 40) /* 40 means 20 dBm. */
- TxPwrIdx = 40;
- else
- TxPwrIdx = (s8)tmp;
- } else if (mode == WIRELESS_MODE_B) {
- bUseDefault = false;
- tmp = (4 * PowerInDbm) - 52;
-
- if (tmp < 0)
- TxPwrIdx = 0;
- else if (tmp > 28) /* 28 means 20 dBm. */
- TxPwrIdx = 28;
- else
- TxPwrIdx = (s8)tmp;
- }
-
- /*
- * TRUE if we want to use a default implementation.
- * We shall set it to FALSE when we have exact translation formula
- * for target IC. 070622, by rcnjko.
- */
- if (bUseDefault) {
- if (PowerInDbm < 0)
- TxPwrIdx = 0;
- else if (PowerInDbm > 35)
- TxPwrIdx = 35;
- else
- TxPwrIdx = (u8)PowerInDbm;
- }
-
- return TxPwrIdx;
-}
-
-void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 max_cck_power_level;
- u8 max_ofdm_power_level;
- u8 min_ofdm_power_level;
- char cck_power_level = (char)(0xff & priv->chtxpwr[ch]);
- char ofdm_power_level = (char)(0xff & priv->chtxpwr_ofdm[ch]);
-
- if (IS_DOT11D_ENABLE(priv->ieee80211) &&
- IS_DOT11D_STATE_DONE(priv->ieee80211)) {
- u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
- u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B,
- MaxTxPwrInDbm);
- u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G,
- MaxTxPwrInDbm);
-
- if (cck_power_level > CckMaxPwrIdx)
- cck_power_level = CckMaxPwrIdx;
- if (ofdm_power_level > OfdmMaxPwrIdx)
- ofdm_power_level = OfdmMaxPwrIdx;
- }
-
- max_cck_power_level = 15;
- max_ofdm_power_level = 25;
- min_ofdm_power_level = 10;
-
- if (cck_power_level > 35)
- cck_power_level = 35;
-
- write_nic_byte(dev, CCK_TXAGC, cck_power_level);
- force_pci_posting(dev);
- mdelay(1);
-
- if (ofdm_power_level > 35)
- ofdm_power_level = 35;
-
- if (priv->up == 0) {
- write_phy_ofdm(dev, 2, 0x42);
- write_phy_ofdm(dev, 5, 0x00);
- write_phy_ofdm(dev, 6, 0x40);
- write_phy_ofdm(dev, 7, 0x00);
- write_phy_ofdm(dev, 8, 0x40);
- }
-
- write_nic_byte(dev, OFDM_TXAGC, ofdm_power_level);
-
- if (ofdm_power_level <= 11) {
- write_phy_ofdm(dev, 0x07, 0x5c);
- write_phy_ofdm(dev, 0x09, 0x5c);
- }
-
- if (ofdm_power_level <= 17) {
- write_phy_ofdm(dev, 0x07, 0x54);
- write_phy_ofdm(dev, 0x09, 0x54);
- } else {
- write_phy_ofdm(dev, 0x07, 0x50);
- write_phy_ofdm(dev, 0x09, 0x50);
- }
-
- force_pci_posting(dev);
- mdelay(1);
-}
-
-void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
-{
- rtl8225z2_SetTXPowerLevel(dev, ch);
-
- RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
-
- if ((RF_ReadReg(dev, 0x7) & 0x0F80) != rtl8225_chan[ch])
- RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
-
- mdelay(1);
-
- force_pci_posting(dev);
- mdelay(10);
-}
-
-static void rtl8225_host_pci_init(struct net_device *dev)
-{
- write_nic_word(dev, RFPinsOutput, 0x480);
-
- rtl8185_rf_pins_enable(dev);
-
- write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO);
-
- write_nic_byte(dev, GP_ENABLE, 0);
-
- force_pci_posting(dev);
- mdelay(200);
-
- /* bit 6 is for RF on/off detection */
- write_nic_word(dev, GP_ENABLE, 0xff & (~(1 << 6)));
-}
-
-void rtl8225z2_rf_init(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int i;
- short channel = 1;
- u16 brsr;
- u32 data;
-
- priv->chan = channel;
-
- rtl8225_host_pci_init(dev);
-
- write_nic_dword(dev, RF_TIMING, 0x000a8008);
-
- brsr = read_nic_word(dev, BRSR);
-
- write_nic_word(dev, BRSR, 0xffff);
-
- write_nic_dword(dev, RF_PARA, 0x100044);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- write_nic_byte(dev, CONFIG3, 0x44);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
- rtl8185_rf_pins_enable(dev);
-
- write_rtl8225(dev, 0x0, 0x2bf); mdelay(1);
- write_rtl8225(dev, 0x1, 0xee0); mdelay(1);
- write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
- write_rtl8225(dev, 0x3, 0x441); mdelay(1);
- write_rtl8225(dev, 0x4, 0x8c3); mdelay(1);
- write_rtl8225(dev, 0x5, 0xc72); mdelay(1);
- write_rtl8225(dev, 0x6, 0xe6); mdelay(1);
- write_rtl8225(dev, 0x7, rtl8225_chan[channel]); mdelay(1);
- write_rtl8225(dev, 0x8, 0x3f); mdelay(1);
- write_rtl8225(dev, 0x9, 0x335); mdelay(1);
- write_rtl8225(dev, 0xa, 0x9d4); mdelay(1);
- write_rtl8225(dev, 0xb, 0x7bb); mdelay(1);
- write_rtl8225(dev, 0xc, 0x850); mdelay(1);
- write_rtl8225(dev, 0xd, 0xcdf); mdelay(1);
- write_rtl8225(dev, 0xe, 0x2b); mdelay(1);
- write_rtl8225(dev, 0xf, 0x114);
-
- mdelay(100);
-
- write_rtl8225(dev, 0x0, 0x1b7);
-
- for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
- write_rtl8225(dev, 0x1, i + 1);
- write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
- }
-
- write_rtl8225(dev, 0x3, 0x80);
- write_rtl8225(dev, 0x5, 0x4);
-
- write_rtl8225(dev, 0x0, 0xb7);
-
- write_rtl8225(dev, 0x2, 0xc4d);
-
- /* FIXME!! rtl8187 we have to check if calibrarion
- * is successful and eventually cal. again (repeat
- * the two write on reg 2)
- */
- data = read_rtl8225(dev, 6);
- if (!(data & 0x00000080)) {
- write_rtl8225(dev, 0x02, 0x0c4d);
- force_pci_posting(dev); mdelay(200);
- write_rtl8225(dev, 0x02, 0x044d);
- force_pci_posting(dev); mdelay(100);
- data = read_rtl8225(dev, 6);
- if (!(data & 0x00000080))
- DMESGW("RF Calibration Failed!!!!\n");
- }
-
- mdelay(200);
-
- write_rtl8225(dev, 0x0, 0x2bf);
-
- for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
- write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
- mdelay(1);
-
- /* enable writing AGC table */
- write_phy_ofdm(dev, 0xa, i + 0x80);
- mdelay(1);
- }
-
- force_pci_posting(dev);
- mdelay(1);
-
- write_phy_ofdm(dev, 0x00, 0x01); mdelay(1);
- write_phy_ofdm(dev, 0x01, 0x02); mdelay(1);
- write_phy_ofdm(dev, 0x02, 0x62); mdelay(1);
- write_phy_ofdm(dev, 0x03, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x04, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x06, 0x40); mdelay(1);
- write_phy_ofdm(dev, 0x07, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x08, 0x40); mdelay(1);
- write_phy_ofdm(dev, 0x09, 0xfe); mdelay(1);
- write_phy_ofdm(dev, 0x0a, 0x08); mdelay(1);
- write_phy_ofdm(dev, 0x0b, 0x80); mdelay(1);
- write_phy_ofdm(dev, 0x0c, 0x01); mdelay(1);
- write_phy_ofdm(dev, 0x0d, 0x43);
- write_phy_ofdm(dev, 0x0e, 0xd3); mdelay(1);
- write_phy_ofdm(dev, 0x0f, 0x38); mdelay(1);
- write_phy_ofdm(dev, 0x10, 0x84); mdelay(1);
- write_phy_ofdm(dev, 0x11, 0x07); mdelay(1);
- write_phy_ofdm(dev, 0x12, 0x20); mdelay(1);
- write_phy_ofdm(dev, 0x13, 0x20); mdelay(1);
- write_phy_ofdm(dev, 0x14, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
- write_phy_ofdm(dev, 0x16, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
- write_phy_ofdm(dev, 0x18, 0xef); mdelay(1);
- write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
- write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
- write_phy_ofdm(dev, 0x1b, 0x15); mdelay(1);
- write_phy_ofdm(dev, 0x1c, 0x04); mdelay(1);
- write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1);
- write_phy_ofdm(dev, 0x1e, 0x95); mdelay(1);
- write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
- write_phy_ofdm(dev, 0x20, 0x1f); mdelay(1);
- write_phy_ofdm(dev, 0x21, 0x17); mdelay(1);
- write_phy_ofdm(dev, 0x22, 0x16); mdelay(1);
- write_phy_ofdm(dev, 0x23, 0x80); mdelay(1); /* FIXME maybe not needed */
- write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
- write_phy_ofdm(dev, 0x25, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
- write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
-
- rtl8225z2_set_gain(dev, 4);
-
- write_phy_cck(dev, 0x0, 0x98); mdelay(1);
- write_phy_cck(dev, 0x3, 0x20); mdelay(1);
- write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
- write_phy_cck(dev, 0x5, 0x12); mdelay(1);
- write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
- write_phy_cck(dev, 0x7, 0x78); mdelay(1);
- write_phy_cck(dev, 0x8, 0x2e); mdelay(1);
- write_phy_cck(dev, 0x10, 0x93); mdelay(1);
- write_phy_cck(dev, 0x11, 0x88); mdelay(1);
- write_phy_cck(dev, 0x12, 0x47); mdelay(1);
- write_phy_cck(dev, 0x13, 0xd0);
- write_phy_cck(dev, 0x19, 0x00);
- write_phy_cck(dev, 0x1a, 0xa0);
- write_phy_cck(dev, 0x1b, 0x08);
- write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
- write_phy_cck(dev, 0x41, 0x8d); mdelay(1);
- write_phy_cck(dev, 0x42, 0x15); mdelay(1);
- write_phy_cck(dev, 0x43, 0x18); mdelay(1);
- write_phy_cck(dev, 0x44, 0x36); mdelay(1);
- write_phy_cck(dev, 0x45, 0x35); mdelay(1);
- write_phy_cck(dev, 0x46, 0x2e); mdelay(1);
- write_phy_cck(dev, 0x47, 0x25); mdelay(1);
- write_phy_cck(dev, 0x48, 0x1c); mdelay(1);
- write_phy_cck(dev, 0x49, 0x12); mdelay(1);
- write_phy_cck(dev, 0x4a, 0x09); mdelay(1);
- write_phy_cck(dev, 0x4b, 0x04); mdelay(1);
- write_phy_cck(dev, 0x4c, 0x05); mdelay(1);
-
- write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
-
- rtl8225z2_SetTXPowerLevel(dev, channel);
-
- /* RX antenna default to A */
- write_phy_cck(dev, 0x11, 0x9b); mdelay(1); /* B: 0xDB */
- write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* B: 0x10 */
-
- rtl8185_tx_antenna(dev, 0x03); /* B: 0x00 */
-
- /* switch to high-speed 3-wire
- * last digit. 2 for both cck and ofdm
- */
- write_nic_dword(dev, 0x94, 0x15c00002);
- rtl8185_rf_pins_enable(dev);
-
- rtl8225z2_rf_set_chan(dev, priv->chan);
-}
-
-#define MAX_DOZE_WAITING_TIMES_85B 20
-#define MAX_POLLING_24F_TIMES_87SE 10
-#define LPS_MAX_SLEEP_WAITING_TIMES_87SE 5
-
-bool SetZebraRFPowerState8185(struct net_device *dev,
- enum rt_rf_power_state eRFPowerState)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 btCR9346, btConfig3;
- bool bActionAllowed = true, bTurnOffBB = true;
- u8 u1bTmp;
- int i;
- bool bResult = true;
- u8 QueueID;
-
- if (priv->SetRFPowerStateInProgress == true)
- return false;
-
- priv->SetRFPowerStateInProgress = true;
-
- btCR9346 = read_nic_byte(dev, CR9346);
- write_nic_byte(dev, CR9346, (btCR9346 | 0xC0));
-
- btConfig3 = read_nic_byte(dev, CONFIG3);
- write_nic_byte(dev, CONFIG3, (btConfig3 | CONFIG3_PARM_En));
-
- switch (eRFPowerState) {
- case RF_ON:
- write_nic_word(dev, 0x37C, 0x00EC);
-
- /* turn on AFE */
- write_nic_byte(dev, 0x54, 0x00);
- write_nic_byte(dev, 0x62, 0x00);
-
- /* turn on RF */
- RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
- RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
-
- /* turn on RF again */
- RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
- RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
-
- /* turn on BB */
- write_phy_ofdm(dev, 0x10, 0x40);
- write_phy_ofdm(dev, 0x12, 0x40);
-
- /* Avoid power down at init time. */
- write_nic_byte(dev, CONFIG4, priv->RFProgType);
-
- u1bTmp = read_nic_byte(dev, 0x24E);
- write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
- break;
- case RF_SLEEP:
- for (QueueID = 0, i = 0; QueueID < 6;) {
- if (get_curr_tx_free_desc(dev, QueueID) ==
- priv->txringcount) {
- QueueID++;
- continue;
- } else {
- priv->TxPollingTimes++;
- if (priv->TxPollingTimes >=
- LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
- bActionAllowed = false;
- break;
- } else
- udelay(10);
- }
- }
-
- if (bActionAllowed) {
- /* turn off BB RXIQ matrix to cut off rx signal */
- write_phy_ofdm(dev, 0x10, 0x00);
- write_phy_ofdm(dev, 0x12, 0x00);
-
- /* turn off RF */
- RF_WriteReg(dev, 0x4, 0x0000);
- RF_WriteReg(dev, 0x0, 0x0000);
-
- /* turn off AFE except PLL */
- write_nic_byte(dev, 0x62, 0xff);
- write_nic_byte(dev, 0x54, 0xec);
-
- mdelay(1);
-
- {
- int i = 0;
- while (true) {
- u8 tmp24F = read_nic_byte(dev, 0x24f);
-
- if ((tmp24F == 0x01) ||
- (tmp24F == 0x09)) {
- bTurnOffBB = true;
- break;
- } else {
- udelay(10);
- i++;
- priv->TxPollingTimes++;
-
- if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
- bTurnOffBB = false;
- break;
- } else
- udelay(10);
- }
- }
- }
-
- if (bTurnOffBB) {
- /* turn off BB */
- u1bTmp = read_nic_byte(dev, 0x24E);
- write_nic_byte(dev, 0x24E,
- (u1bTmp | BIT5 | BIT6));
-
- /* turn off AFE PLL */
- write_nic_byte(dev, 0x54, 0xFC);
- write_nic_word(dev, 0x37C, 0x00FC);
- }
- }
- break;
- case RF_OFF:
- for (QueueID = 0, i = 0; QueueID < 6;) {
- if (get_curr_tx_free_desc(dev, QueueID) ==
- priv->txringcount) {
- QueueID++;
- continue;
- } else {
- udelay(10);
- i++;
- }
-
- if (i >= MAX_DOZE_WAITING_TIMES_85B)
- break;
- }
-
- /* turn off BB RXIQ matrix to cut off rx signal */
- write_phy_ofdm(dev, 0x10, 0x00);
- write_phy_ofdm(dev, 0x12, 0x00);
-
- /* turn off RF */
- RF_WriteReg(dev, 0x4, 0x0000);
- RF_WriteReg(dev, 0x0, 0x0000);
-
- /* turn off AFE except PLL */
- write_nic_byte(dev, 0x62, 0xff);
- write_nic_byte(dev, 0x54, 0xec);
-
- mdelay(1);
-
- {
- int i = 0;
-
- while (true) {
- u8 tmp24F = read_nic_byte(dev, 0x24f);
-
- if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
- bTurnOffBB = true;
- break;
- } else {
- bTurnOffBB = false;
- udelay(10);
- i++;
- }
-
- if (i > MAX_POLLING_24F_TIMES_87SE)
- break;
- }
- }
-
- if (bTurnOffBB) {
- /* turn off BB */
- u1bTmp = read_nic_byte(dev, 0x24E);
- write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
-
- /* turn off AFE PLL (80M) */
- write_nic_byte(dev, 0x54, 0xFC);
- write_nic_word(dev, 0x37C, 0x00FC);
- }
- break;
- }
-
- btConfig3 &= ~(CONFIG3_PARM_En);
- write_nic_byte(dev, CONFIG3, btConfig3);
-
- btCR9346 &= ~(0xC0);
- write_nic_byte(dev, CR9346, btCR9346);
-
- if (bResult && bActionAllowed)
- priv->eRFPowerState = eRFPowerState;
-
- priv->SetRFPowerStateInProgress = false;
-
- return bResult && bActionAllowed;
-}
-
-void rtl8225z4_rf_sleep(struct net_device *dev)
-{
- MgntActSet_RF_State(dev, RF_SLEEP, RF_CHANGE_BY_PS);
-}
-
-void rtl8225z4_rf_wakeup(struct net_device *dev)
-{
- MgntActSet_RF_State(dev, RF_ON, RF_CHANGE_BY_PS);
-}
+++ /dev/null
-/*
- This file contains wireless extension handlers.
-
- This is part of rtl8180 OpenSource driver.
- Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
- Released under the terms of GPL (General Public Licence)
-
- Parts of this driver are based on the GPL part
- of the official realtek driver.
-
- Parts of this driver are based on the rtl8180 driver skeleton
- from Patric Schenke & Andres Salomon.
-
- Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
-
- We want to thanks the Authors of those projects and the Ndiswrapper
- project Authors.
-*/
-
-
-#include "r8180.h"
-#include "r8180_hw.h"
-
-#include <net/iw_handler.h>
-#include "ieee80211/dot11d.h"
-
-static u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
- 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
-
-#define RATE_COUNT ARRAY_SIZE(rtl8180_rates)
-
-static struct rtl8187se_channel_list default_channel_plan[] = {
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19}, /* FCC */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* IC */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* ETSI */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* Spain. Change to ETSI. */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* France. Change to ETSI. */
- {{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9}, /* MKK */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, /* MKK1 */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* Israel */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17}, /* For 11a , TELEC */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14} /* For Global Domain. 1-11:active scan, 12-14 passive scan.*/ /* +YJ, 080626 */
-};
-static int r8180_wx_get_freq(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
-}
-
-
-static int r8180_wx_set_key(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct iw_point *erq = &(wrqu->encoding);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- if (erq->length > 0) {
- u32 *tkey = (u32 *) key;
- priv->key0[0] = tkey[0];
- priv->key0[1] = tkey[1];
- priv->key0[2] = tkey[2];
- priv->key0[3] = tkey[3] & 0xff;
- DMESG("Setting wep key to %x %x %x %x",
- tkey[0], tkey[1], tkey[2], tkey[3]);
- rtl8180_set_hw_wep(dev);
- }
- return 0;
-}
-
-
-static int r8180_wx_set_beaconinterval(struct net_device *dev,
- struct iw_request_info *aa,
- union iwreq_data *wrqu, char *b)
-{
- int *parms = (int *)b;
- int bi = parms[0];
-
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- DMESG("setting beacon interval to %x", bi);
-
- priv->ieee80211->current_network.beacon_interval = bi;
- rtl8180_commit(dev);
- up(&priv->wx_sem);
-
- return 0;
-}
-
-
-
-static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
-}
-
-
-
-static int r8180_wx_get_rate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
-}
-
-
-
-static int r8180_wx_set_rate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-
-static int r8180_wx_set_crcmon(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int *parms = (int *)extra;
- int enable = (parms[0] > 0);
- short prev = priv->crcmon;
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- if (enable)
- priv->crcmon = 1;
- else
- priv->crcmon = 0;
-
- DMESG("bad CRC in monitor mode are %s",
- priv->crcmon ? "accepted" : "rejected");
-
- if (prev != priv->crcmon && priv->up) {
- rtl8180_down(dev);
- rtl8180_up(dev);
- }
-
- up(&priv->wx_sem);
-
- return 0;
-}
-
-
-static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret;
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- if (priv->bInactivePs) {
- if (wrqu->mode == IW_MODE_ADHOC)
- IPSLeave(dev);
- }
- ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
-
- up(&priv->wx_sem);
- return ret;
-}
-
-/* YJ,add,080819,for hidden ap */
-struct iw_range_with_scan_capa {
- /* Informative stuff (to choose between different interface) */
-
- __u32 throughput; /* To give an idea... */
-
- /* In theory this value should be the maximum benchmarked
- * TCP/IP throughput, because with most of these devices the
- * bit rate is meaningless (overhead an co) to estimate how
- * fast the connection will go and pick the fastest one.
- * I suggest people to play with Netperf or any benchmark...
- */
-
- /* NWID (or domain id) */
- __u32 min_nwid; /* Minimal NWID we are able to set */
- __u32 max_nwid; /* Maximal NWID we are able to set */
-
- /* Old Frequency (backward compat - moved lower ) */
- __u16 old_num_channels;
- __u8 old_num_frequency;
-
- /* Scan capabilities */
- __u8 scan_capa;
-};
-/* YJ,add,080819,for hidden ap */
-
-
-static int rtl8180_wx_get_range(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_range *range = (struct iw_range *)extra;
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 val;
- int i;
-
- wrqu->data.length = sizeof(*range);
- memset(range, 0, sizeof(*range));
-
- /* Let's try to keep this struct in the same order as in
- * linux/include/wireless.h
- */
-
- /* TODO: See what values we can set, and remove the ones we can't
- * set, or fill them with some default data.
- */
-
- /* ~5 Mb/s real (802.11b) */
- range->throughput = 5 * 1000 * 1000;
-
- /* TODO: Not used in 802.11b? */
-/* range->min_nwid; */ /* Minimal NWID we are able to set */
- /* TODO: Not used in 802.11b? */
-/* range->max_nwid; */ /* Maximal NWID we are able to set */
-
- /* Old Frequency (backward compat - moved lower ) */
-/* range->old_num_channels; */
-/* range->old_num_frequency; */
-/* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
- if (priv->rf_set_sens != NULL)
- range->sensitivity = priv->max_sens; /* signal level threshold range */
-
- range->max_qual.qual = 100;
- /* TODO: Find real max RSSI and stick here */
- range->max_qual.level = 0;
- range->max_qual.noise = -98;
- range->max_qual.updated = 7; /* Updated all three */
-
- range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
- /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
- range->avg_qual.level = 20 + -98;
- range->avg_qual.noise = 0;
- range->avg_qual.updated = 7; /* Updated all three */
-
- range->num_bitrates = RATE_COUNT;
-
- for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
- range->bitrate[i] = rtl8180_rates[i];
-
- range->min_frag = MIN_FRAG_THRESHOLD;
- range->max_frag = MAX_FRAG_THRESHOLD;
-
- range->pm_capa = 0;
-
- range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 16;
-
- range->num_channels = 14;
-
- for (i = 0, val = 0; i < 14; i++) {
-
- /* Include only legal frequencies for some countries */
- if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
- range->freq[val].i = i + 1;
- range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
- range->freq[val].e = 1;
- val++;
- } else {
- /* FIXME: do we need to set anything for channels */
- /* we don't use ? */
- }
-
- if (val == IW_MAX_FREQUENCIES)
- break;
- }
-
- range->num_frequency = val;
- range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
- IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-
- return 0;
-}
-
-
-static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret;
- struct ieee80211_device *ieee = priv->ieee80211;
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
- struct iw_scan_req *req = (struct iw_scan_req *)b;
- if (req->essid_len) {
- ieee->current_network.ssid_len = req->essid_len;
- memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
- }
- }
-
- down(&priv->wx_sem);
- if (priv->up) {
- priv->ieee80211->actscanning = true;
- if (priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)) {
- IPSLeave(dev);
- ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
- ret = 0;
- } else {
- /* prevent scan in BusyTraffic */
- /* FIXME: Need to consider last scan time */
- if ((priv->link_detect.b_busy_traffic) && (true)) {
- ret = 0;
- printk("Now traffic is busy, please try later!\n");
- } else
- /* prevent scan in BusyTraffic,end */
- ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
- }
- } else
- ret = -1;
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-
-static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
-
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- down(&priv->wx_sem);
- if (priv->up)
- ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
- else
- ret = -1;
-
- up(&priv->wx_sem);
- return ret;
-}
-
-
-static int r8180_wx_set_essid(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- int ret;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- if (priv->bInactivePs)
- IPSLeave(dev);
-
- ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
-
- up(&priv->wx_sem);
- return ret;
-}
-
-
-static int r8180_wx_get_essid(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-
-static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
-
- up(&priv->wx_sem);
- return ret;
-}
-
-
-static int r8180_wx_get_name(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
-}
-
-static int r8180_wx_set_frag(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- if (wrqu->frag.disabled)
- priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
- else {
- if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
- wrqu->frag.value > MAX_FRAG_THRESHOLD)
- return -EINVAL;
-
- priv->ieee80211->fts = wrqu->frag.value & ~0x1;
- }
-
- return 0;
-}
-
-
-static int r8180_wx_get_frag(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- wrqu->frag.value = priv->ieee80211->fts;
- wrqu->frag.fixed = 0; /* no auto select */
- wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
-
- return 0;
-}
-
-
-static int r8180_wx_set_wap(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *awrq, char *extra)
-{
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
-
- up(&priv->wx_sem);
- return ret;
-
-}
-
-
-static int r8180_wx_get_wap(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
-}
-
-
-static int r8180_wx_set_enc(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
-
- down(&priv->wx_sem);
-
- if (priv->hw_wep)
- ret = r8180_wx_set_key(dev, info, wrqu, key);
- else {
- DMESG("Setting SW wep key");
- ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
- }
-
- up(&priv->wx_sem);
- return ret;
-}
-
-
-static int r8180_wx_get_enc(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
-}
-
-
-static int r8180_wx_set_scan_type(struct net_device *dev,
- struct iw_request_info *aa,
- union iwreq_data *wrqu, char *p)
-{
-
- struct r8180_priv *priv = ieee80211_priv(dev);
- int *parms = (int *)p;
- int mode = parms[0];
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- priv->ieee80211->active_scan = mode;
-
- return 1;
-}
-
-static int r8180_wx_set_retry(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int err = 0;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
- wrqu->retry.disabled) {
- err = -EINVAL;
- goto exit;
- }
- if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
- err = -EINVAL;
- goto exit;
- }
-
- if (wrqu->retry.value > R8180_MAX_RETRY) {
- err = -EINVAL;
- goto exit;
- }
- if (wrqu->retry.flags & IW_RETRY_MAX) {
- priv->retry_rts = wrqu->retry.value;
- DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
-
- } else {
- priv->retry_data = wrqu->retry.value;
- DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
- }
-
- /* FIXME !
- * We might try to write directly the TX config register
- * or to restart just the (R)TX process.
- * I'm unsure if whole reset is really needed
- */
-
- rtl8180_commit(dev);
-exit:
- up(&priv->wx_sem);
-
- return err;
-}
-
-static int r8180_wx_get_retry(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- wrqu->retry.disabled = 0; /* can't be disabled */
-
- if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
- IW_RETRY_LIFETIME)
- return -EINVAL;
-
- if (wrqu->retry.flags & IW_RETRY_MAX) {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
- wrqu->retry.value = priv->retry_rts;
- } else {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
- wrqu->retry.value = priv->retry_data;
- }
-
- return 0;
-}
-
-static int r8180_wx_get_sens(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- if (priv->rf_set_sens == NULL)
- return -1; /* we have not this support for this radio */
- wrqu->sens.value = priv->sens;
- return 0;
-}
-
-
-static int r8180_wx_set_sens(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
-
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- short err = 0;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- if (priv->rf_set_sens == NULL) {
- err = -1; /* we have not this support for this radio */
- goto exit;
- }
- if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
- priv->sens = wrqu->sens.value;
- else
- err = -EINVAL;
-
-exit:
- up(&priv->wx_sem);
-
- return err;
-}
-
-
-static int r8180_wx_set_rawtx(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
-
- up(&priv->wx_sem);
-
- return ret;
-
-}
-
-static int r8180_wx_get_power(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-static int r8180_wx_set_power(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu->power.disabled, wrqu->power.flags);
- if (wrqu->power.disabled == 0) {
- wrqu->power.flags |= IW_POWER_ALL_R;
- wrqu->power.flags |= IW_POWER_TIMEOUT;
- wrqu->power.value = 1000;
- }
-
- ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-static int r8180_wx_set_rts(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- if (wrqu->rts.disabled)
- priv->rts = DEFAULT_RTS_THRESHOLD;
- else {
- if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
- wrqu->rts.value > MAX_RTS_THRESHOLD)
- return -EINVAL;
-
- priv->rts = wrqu->rts.value;
- }
-
- return 0;
-}
-static int r8180_wx_get_rts(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-
- wrqu->rts.value = priv->rts;
- wrqu->rts.fixed = 0; /* no auto select */
- wrqu->rts.disabled = (wrqu->rts.value == 0);
-
- return 0;
-}
-static int dummy(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- return -1;
-}
-
-static int r8180_wx_get_iwmode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee;
- int ret = 0;
-
-
-
- down(&priv->wx_sem);
-
- ieee = priv->ieee80211;
-
- strcpy(extra, "802.11");
- if (ieee->modulation & IEEE80211_CCK_MODULATION) {
- strcat(extra, "b");
- if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- strcat(extra, "/g");
- } else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- strcat(extra, "g");
-
- up(&priv->wx_sem);
-
- return ret;
-}
-static int r8180_wx_set_iwmode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
- int *param = (int *)extra;
- int ret = 0;
- int modulation = 0, mode = 0;
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- if (*param == 1) {
- modulation |= IEEE80211_CCK_MODULATION;
- mode = IEEE_B;
- printk(KERN_INFO "B mode!\n");
- } else if (*param == 2) {
- modulation |= IEEE80211_OFDM_MODULATION;
- mode = IEEE_G;
- printk(KERN_INFO "G mode!\n");
- } else if (*param == 3) {
- modulation |= IEEE80211_CCK_MODULATION;
- modulation |= IEEE80211_OFDM_MODULATION;
- mode = IEEE_B|IEEE_G;
- printk(KERN_INFO "B/G mode!\n");
- }
-
- if (ieee->proto_started) {
- ieee80211_stop_protocol(ieee);
- ieee->mode = mode;
- ieee->modulation = modulation;
- ieee80211_start_protocol(ieee);
- } else {
- ieee->mode = mode;
- ieee->modulation = modulation;
- }
-
- up(&priv->wx_sem);
-
- return ret;
-}
-static int r8180_wx_get_preamble(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-
- down(&priv->wx_sem);
-
-
-
- *extra = (char) priv->plcp_preamble_mode; /* 0:auto 1:short 2:long */
- up(&priv->wx_sem);
-
- return 0;
-}
-static int r8180_wx_set_preamble(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret = 0;
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- if (*extra < 0 || *extra > 2)
- ret = -1;
- else
- priv->plcp_preamble_mode = *((short *)extra);
-
-
-
- up(&priv->wx_sem);
-
- return ret;
-}
-static int r8180_wx_get_siglevel(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret = 0;
-
-
-
- down(&priv->wx_sem);
- /* Modify by hikaru 6.5 */
- *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
-
-
-
- up(&priv->wx_sem);
-
- return ret;
-}
-static int r8180_wx_get_sigqual(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret = 0;
-
-
-
- down(&priv->wx_sem);
- /* Modify by hikaru 6.5 */
- *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
-
-
-
- up(&priv->wx_sem);
-
- return ret;
-}
-static int r8180_wx_reset_stats(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- down(&priv->wx_sem);
-
- priv->stats.txrdu = 0;
- priv->stats.rxrdu = 0;
- priv->stats.rxnolast = 0;
- priv->stats.rxnodata = 0;
- priv->stats.rxnopointer = 0;
- priv->stats.txnperr = 0;
- priv->stats.txresumed = 0;
- priv->stats.rxerr = 0;
- priv->stats.rxoverflow = 0;
- priv->stats.rxint = 0;
-
- priv->stats.txnpokint = 0;
- priv->stats.txhpokint = 0;
- priv->stats.txhperr = 0;
- priv->stats.ints = 0;
- priv->stats.shints = 0;
- priv->stats.txoverflow = 0;
- priv->stats.rxdmafail = 0;
- priv->stats.txbeacon = 0;
- priv->stats.txbeaconerr = 0;
- priv->stats.txlpokint = 0;
- priv->stats.txlperr = 0;
- priv->stats.txretry = 0;/* 20060601 */
- priv->stats.rxcrcerrmin = 0 ;
- priv->stats.rxcrcerrmid = 0;
- priv->stats.rxcrcerrmax = 0;
- priv->stats.rxicverr = 0;
-
- up(&priv->wx_sem);
-
- return 0;
-
-}
-static int r8180_wx_radio_on(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
-
- down(&priv->wx_sem);
- priv->rf_wakeup(dev);
-
- up(&priv->wx_sem);
-
- return 0;
-
-}
-
-static int r8180_wx_radio_off(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
-
- down(&priv->wx_sem);
- priv->rf_sleep(dev);
-
- up(&priv->wx_sem);
-
- return 0;
-
-}
-static int r8180_wx_get_channelplan(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-
- down(&priv->wx_sem);
- *extra = priv->channel_plan;
-
-
-
- up(&priv->wx_sem);
-
- return 0;
-}
-static int r8180_wx_set_channelplan(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int *val = (int *)extra;
- int i;
- printk("-----in fun %s\n", __func__);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- /* unsigned long flags; */
- down(&priv->wx_sem);
- if (default_channel_plan[*val].len != 0) {
- priv->channel_plan = *val;
- /* Clear old channel map 8 */
- for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
- GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
-
- /* Set new channel map */
- for (i = 1; i <= default_channel_plan[*val].len; i++)
- GET_DOT11D_INFO(priv->ieee80211)->channel_map[default_channel_plan[*val].channel[i-1]] = 1;
-
- }
- up(&priv->wx_sem);
-
- return 0;
-}
-
-static int r8180_wx_get_version(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- /* struct ieee80211_device *ieee; */
-
- down(&priv->wx_sem);
- strcpy(extra, "1020.0808");
- up(&priv->wx_sem);
-
- return 0;
-}
-
-/* added by amy 080818 */
-/*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
-static int r8180_wx_set_forcerate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 forcerate = *extra;
-
- down(&priv->wx_sem);
-
- printk("==============>%s(): forcerate is %d\n", __func__, forcerate);
- if ((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
- (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
- (forcerate == 96) || (forcerate == 108)) {
- priv->ForcedDataRate = 1;
- priv->ieee80211->rate = forcerate * 5;
- } else if (forcerate == 0) {
- priv->ForcedDataRate = 0;
- printk("OK! return rate adaptive\n");
- } else
- printk("ERR: wrong rate\n");
- up(&priv->wx_sem);
- return 0;
-}
-
-static int r8180_wx_set_enc_ext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
-
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- int ret = 0;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
- up(&priv->wx_sem);
- return ret;
-
-}
-static int r8180_wx_set_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret = 0;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
- up(&priv->wx_sem);
- return ret;
-}
-
-static int r8180_wx_set_mlme(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
-
- down(&priv->wx_sem);
-#if 1
- ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
-#endif
- up(&priv->wx_sem);
- return ret;
-}
-static int r8180_wx_set_gen_ie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-#if 1
- ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
-#endif
- up(&priv->wx_sem);
- return ret;
-
-
-}
-
-static const iw_handler r8180_wx_handlers[] = {
- IW_HANDLER(SIOCGIWNAME, r8180_wx_get_name),
- IW_HANDLER(SIOCSIWNWID, dummy),
- IW_HANDLER(SIOCGIWNWID, dummy),
- IW_HANDLER(SIOCSIWFREQ, r8180_wx_set_freq),
- IW_HANDLER(SIOCGIWFREQ, r8180_wx_get_freq),
- IW_HANDLER(SIOCSIWMODE, r8180_wx_set_mode),
- IW_HANDLER(SIOCGIWMODE, r8180_wx_get_mode),
- IW_HANDLER(SIOCSIWSENS, r8180_wx_set_sens),
- IW_HANDLER(SIOCGIWSENS, r8180_wx_get_sens),
- IW_HANDLER(SIOCGIWRANGE, rtl8180_wx_get_range),
- IW_HANDLER(SIOCSIWSPY, dummy),
- IW_HANDLER(SIOCGIWSPY, dummy),
- IW_HANDLER(SIOCSIWAP, r8180_wx_set_wap),
- IW_HANDLER(SIOCGIWAP, r8180_wx_get_wap),
- IW_HANDLER(SIOCSIWMLME, r8180_wx_set_mlme),
- IW_HANDLER(SIOCGIWAPLIST, dummy), /* deprecated */
- IW_HANDLER(SIOCSIWSCAN, r8180_wx_set_scan),
- IW_HANDLER(SIOCGIWSCAN, r8180_wx_get_scan),
- IW_HANDLER(SIOCSIWESSID, r8180_wx_set_essid),
- IW_HANDLER(SIOCGIWESSID, r8180_wx_get_essid),
- IW_HANDLER(SIOCSIWNICKN, dummy),
- IW_HANDLER(SIOCGIWNICKN, dummy),
- IW_HANDLER(SIOCSIWRATE, r8180_wx_set_rate),
- IW_HANDLER(SIOCGIWRATE, r8180_wx_get_rate),
- IW_HANDLER(SIOCSIWRTS, r8180_wx_set_rts),
- IW_HANDLER(SIOCGIWRTS, r8180_wx_get_rts),
- IW_HANDLER(SIOCSIWFRAG, r8180_wx_set_frag),
- IW_HANDLER(SIOCGIWFRAG, r8180_wx_get_frag),
- IW_HANDLER(SIOCSIWTXPOW, dummy),
- IW_HANDLER(SIOCGIWTXPOW, dummy),
- IW_HANDLER(SIOCSIWRETRY, r8180_wx_set_retry),
- IW_HANDLER(SIOCGIWRETRY, r8180_wx_get_retry),
- IW_HANDLER(SIOCSIWENCODE, r8180_wx_set_enc),
- IW_HANDLER(SIOCGIWENCODE, r8180_wx_get_enc),
- IW_HANDLER(SIOCSIWPOWER, r8180_wx_set_power),
- IW_HANDLER(SIOCGIWPOWER, r8180_wx_get_power),
- IW_HANDLER(SIOCSIWGENIE, r8180_wx_set_gen_ie),
- IW_HANDLER(SIOCSIWAUTH, r8180_wx_set_auth),
- IW_HANDLER(SIOCSIWENCODEEXT, r8180_wx_set_enc_ext),
-};
-
-static const struct iw_priv_args r8180_private_args[] = {
- {
- SIOCIWFIRSTPRIV + 0x0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
- },
- { SIOCIWFIRSTPRIV + 0x1,
- 0, 0, "dummy"
-
- },
- {
- SIOCIWFIRSTPRIV + 0x2,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
- },
- { SIOCIWFIRSTPRIV + 0x3,
- 0, 0, "dummy"
-
- },
- {
- SIOCIWFIRSTPRIV + 0x4,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
-
- },
- { SIOCIWFIRSTPRIV + 0x5,
- 0, 0, "dummy"
-
- },
- {
- SIOCIWFIRSTPRIV + 0x6,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
-
- },
- { SIOCIWFIRSTPRIV + 0x7,
- 0, 0, "dummy"
-
- },
- {
- SIOCIWFIRSTPRIV + 0x8,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
- },
- {
- SIOCIWFIRSTPRIV + 0x9,
- 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
- },
- {
- SIOCIWFIRSTPRIV + 0xA,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
- },
- {
- SIOCIWFIRSTPRIV + 0xB,
- 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
- },
- { SIOCIWFIRSTPRIV + 0xC,
- 0, 0, "dummy"
- },
- {
- SIOCIWFIRSTPRIV + 0xD,
- 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
- },
- { SIOCIWFIRSTPRIV + 0xE,
- 0, 0, "dummy"
- },
- {
- SIOCIWFIRSTPRIV + 0xF,
- 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
- },
- {
- SIOCIWFIRSTPRIV + 0x10,
- 0, 0, "resetstats"
- },
- {
- SIOCIWFIRSTPRIV + 0x11,
- 0, 0, "dummy"
- },
- {
- SIOCIWFIRSTPRIV + 0x12,
- 0, 0, "radioon"
- },
- {
- SIOCIWFIRSTPRIV + 0x13,
- 0, 0, "radiooff"
- },
- {
- SIOCIWFIRSTPRIV + 0x14,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
- },
- {
- SIOCIWFIRSTPRIV + 0x15,
- 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
- },
- {
- SIOCIWFIRSTPRIV + 0x16,
- 0, 0, "dummy"
- },
- {
- SIOCIWFIRSTPRIV + 0x17,
- 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
- },
- {
- SIOCIWFIRSTPRIV + 0x18,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
- },
-};
-
-
-static iw_handler r8180_private_handler[] = {
- r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
- dummy,
- r8180_wx_set_beaconinterval,
- dummy,
- /* r8180_wx_set_monitor_type, */
- r8180_wx_set_scan_type,
- dummy,
- r8180_wx_set_rawtx,
- dummy,
- r8180_wx_set_iwmode,
- r8180_wx_get_iwmode,
- r8180_wx_set_preamble,
- r8180_wx_get_preamble,
- dummy,
- r8180_wx_get_siglevel,
- dummy,
- r8180_wx_get_sigqual,
- r8180_wx_reset_stats,
- dummy,/* r8180_wx_get_stats */
- r8180_wx_radio_on,
- r8180_wx_radio_off,
- r8180_wx_set_channelplan,
- r8180_wx_get_channelplan,
- dummy,
- r8180_wx_get_version,
- r8180_wx_set_forcerate,
-};
-
-static inline int is_same_network(struct ieee80211_network *src,
- struct ieee80211_network *dst,
- struct ieee80211_device *ieee)
-{
- /* A network is only a duplicate if the channel, BSSID, ESSID
- * and the capability field (in particular IBSS and BSS) all match.
- * We treat all <hidden> with the same BSSID and channel
- * as one network
- */
- if (src->channel != dst->channel)
- return 0;
-
- if (memcmp(src->bssid, dst->bssid, ETH_ALEN) != 0)
- return 0;
-
- if (ieee->iw_mode != IW_MODE_INFRA) {
- if (src->ssid_len != dst->ssid_len)
- return 0;
- if (memcmp(src->ssid, dst->ssid, src->ssid_len) != 0)
- return 0;
- }
-
- if ((src->capability & WLAN_CAPABILITY_IBSS) !=
- (dst->capability & WLAN_CAPABILITY_IBSS))
- return 0;
- if ((src->capability & WLAN_CAPABILITY_BSS) !=
- (dst->capability & WLAN_CAPABILITY_BSS))
- return 0;
-
- return 1;
-}
-
-/* WB modified to show signal to GUI on 18-01-2008 */
-static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
- struct iw_statistics *wstats = &priv->wstats;
- int tmp_level = 0;
- int tmp_qual = 0;
- int tmp_noise = 0;
-
- if (ieee->state < IEEE80211_LINKED) {
- wstats->qual.qual = 0;
- wstats->qual.level = 0;
- wstats->qual.noise = 0;
- wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- return wstats;
- }
-
- tmp_level = (&ieee->current_network)->stats.signal;
- tmp_qual = (&ieee->current_network)->stats.signalstrength;
- tmp_noise = (&ieee->current_network)->stats.noise;
-
- wstats->qual.level = tmp_level;
- wstats->qual.qual = tmp_qual;
- wstats->qual.noise = tmp_noise;
- wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- return wstats;
-}
-
-struct iw_handler_def r8180_wx_handlers_def = {
- .standard = r8180_wx_handlers,
- .num_standard = ARRAY_SIZE(r8180_wx_handlers),
- .private = r8180_private_handler,
- .num_private = ARRAY_SIZE(r8180_private_handler),
- .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
- .get_wireless_stats = r8180_get_wireless_stats,
- .private_args = (struct iw_priv_args *)r8180_private_args,
-};
-
-
+++ /dev/null
-/*
- This is part of rtl8180 OpenSource driver - v 0.3
- Copyright (C) Andrea Merello 2004 <andrea.merello@gmail.com>
- Released under the terms of GPL (General Public Licence)
-
- Parts of this driver are based on the GPL part of the official realtek driver
- Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
- Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-
- We want to thanks the Authors of such projects and the Ndiswrapper project Authors.
-*/
-
-/* this file (will) contains wireless extension handlers*/
-
-#ifndef R8180_WX_H
-#define R8180_WX_H
-#include <linux/wireless.h>
-#include "ieee80211/ieee80211.h"
-extern struct iw_handler_def r8180_wx_handlers_def;
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
- *
- * Module Name:
- * r8185b_init.c
- *
- * Abstract:
- * Hardware Initialization and Hardware IO for RTL8185B
- *
- * Major Change History:
- * When Who What
- * ---------- --------------- -------------------------------
- * 2006-11-15 Xiong Created
- *
- * Notes:
- * This file is ported from RTL8185B Windows driver.
- *
- *
- */
-
-/*--------------------------Include File------------------------------------*/
-#include <linux/spinlock.h>
-#include "r8180_hw.h"
-#include "r8180.h"
-#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
-#include "r8180_93cx6.h" /* Card EEPROM */
-#include "r8180_wx.h"
-#include "ieee80211/dot11d.h"
-/* #define CONFIG_RTL8180_IO_MAP */
-#define TC_3W_POLL_MAX_TRY_CNT 5
-
-static u8 MAC_REG_TABLE[][2] = {
- /*
- * PAGE 0:
- * 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in
- * HwConfigureRTL8185()
- * 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185().
- * 0x1F0~0x1F8 set in MacConfig_85BASIC()
- */
- {0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42},
- {0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03},
- {0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03},
- {0x94, 0x0F}, {0x95, 0x32},
- {0x96, 0x00}, {0x97, 0x07}, {0xb4, 0x22}, {0xdb, 0x00},
- {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32},
- {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4},
- {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00},
- {0xff, 0x00},
-
- /*
- * PAGE 1:
- * For Flextronics system Logo PCIHCT failure:
- * 0x1C4~0x1CD set no-zero value to avoid PCI configuration
- * space 0x45[7]=1
- */
- {0x5e, 0x01},
- {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24},
- {0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF},
- {0x82, 0xFF}, {0x83, 0x03},
- /* lzm add 080826 */
- {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22},
- /* lzm add 080826 */
- {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22},
- {0xe2, 0x00},
-
-
- /* PAGE 2: */
- {0x5e, 0x02},
- {0x0c, 0x04}, {0x4c, 0x30}, {0x4d, 0x08}, {0x50, 0x05}, {0x51, 0xf5},
- {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0xff}, {0x55, 0xff}, {0x56, 0xff},
- {0x57, 0xff}, {0x58, 0x08}, {0x59, 0x08}, {0x5a, 0x08}, {0x5b, 0x08},
- {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08}, {0x63, 0x08}, {0x64, 0x2f},
- {0x8c, 0x3f}, {0x8d, 0x3f}, {0x8e, 0x3f},
- {0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff},
- {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00},
-
- /* PAGE 0: */
- {0x5e, 0x00}, {0x9f, 0x03}
- };
-
-
-static u8 ZEBRA_AGC[] = {
- 0,
- 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76,
- 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A,
- 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x48, 0x47, 0x46, 0x45,
- 0x44, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07,
- 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, 0x17, 0x17, 0x18, 0x18,
- 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e,
- 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22,
- 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
- 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F
- };
-
-static u32 ZEBRA_RF_RX_GAIN_TABLE[] = {
- 0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6,
- 0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057,
- 0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3,
- 0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3,
- 0x0183, 0x0163, 0x0143, 0x0123, 0x0103
- };
-
-static u8 OFDM_CONFIG[] = {
- /* OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX */
- /* OFDM reg0x3C[4]=1'b1: Enable RX power saving mode */
- /* ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test */
- /* 0x00 */
- 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50,
- 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00,
- /* 0x10 */
- 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26,
- 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB,
- /* 0x20 */
- 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00,
- 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00,
- /* 0x30 */
- 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e,
- 0xD8, 0x3C, 0x7B, 0x10, 0x10
- };
-
- /*---------------------------------------------------------------
- * Hardware IO
- * the code is ported from Windows source code
- *---------------------------------------------------------------
- */
-
-static u8 PlatformIORead1Byte(struct net_device *dev, u32 offset)
-{
- return read_nic_byte(dev, offset);
-}
-
-static void PlatformIOWrite1Byte(struct net_device *dev, u32 offset, u8 data)
-{
- write_nic_byte(dev, offset, data);
- /*
- * To make sure write operation is completed,
- * 2005.11.09, by rcnjko.
- */
- read_nic_byte(dev, offset);
-}
-
-static void PlatformIOWrite2Byte(struct net_device *dev, u32 offset, u16 data)
-{
- write_nic_word(dev, offset, data);
- /*
- * To make sure write operation is completed,
- * 2005.11.09, by rcnjko.
- */
- read_nic_word(dev, offset);
-}
-
-static void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data)
-{
- if (offset == PhyAddr) {
- /* For Base Band configuration. */
- unsigned char cmdByte;
- unsigned long dataBytes;
- unsigned char idx;
- u8 u1bTmp;
-
- cmdByte = (u8)(data & 0x000000ff);
- dataBytes = data>>8;
-
- /*
- * 071010, rcnjko:
- * The critical section is only BB read/write race
- * condition. Assumption:
- * 1. We assume NO one will access BB at DIRQL, otherwise,
- * system will crash for
- * acquiring the spinlock in such context.
- * 2. PlatformIOWrite4Byte() MUST NOT be recursive.
- */
- /* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */
-
- for (idx = 0; idx < 30; idx++) {
- /* Make sure command bit is clear before access it. */
- u1bTmp = PlatformIORead1Byte(dev, PhyAddr);
- if ((u1bTmp & BIT7) == 0)
- break;
- else
- mdelay(10);
- }
-
- for (idx = 0; idx < 3; idx++)
- PlatformIOWrite1Byte(dev, offset+1+idx,
- ((u8 *)&dataBytes)[idx]);
-
- write_nic_byte(dev, offset, cmdByte);
-
- /* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */
- } else {
- write_nic_dword(dev, offset, data);
- /*
- * To make sure write operation is completed, 2005.11.09,
- * by rcnjko.
- */
- read_nic_dword(dev, offset);
- }
-}
-
-static void SetOutputEnableOfRfPins(struct net_device *dev)
-{
- write_nic_word(dev, RFPinsEnable, 0x1bff);
-}
-
-static bool HwHSSIThreeWire(struct net_device *dev,
- u8 *pDataBuf,
- bool write)
-{
- u8 TryCnt;
- u8 u1bTmp;
-
- /* Check if WE and RE are cleared. */
- for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
- u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
- if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0)
- break;
-
- udelay(10);
- }
- if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) {
- netdev_err(dev,
- "HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n",
- u1bTmp);
- return false;
- }
-
- /* RTL8187S HSSI Read/Write Function */
- u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
- u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */
- write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
-
- /* jong: HW SI read must set reg84[3]=0. */
- u1bTmp = read_nic_byte(dev, RFPinsSelect);
- u1bTmp &= ~BIT3;
- write_nic_byte(dev, RFPinsSelect, u1bTmp);
- /* Fill up data buffer for write operation. */
-
- /* SI - reg274[3:0] : RF register's Address */
- if (write)
- write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
- else
- write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
-
- /* Set up command: WE or RE. */
- if (write)
- write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
- else
- write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
-
-
- /* Check if DONE is set. */
- for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
- u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
- if (u1bTmp & SW_3W_CMD1_DONE)
- break;
-
- udelay(10);
- }
-
- write_nic_byte(dev, SW_3W_CMD1, 0);
-
- /* Read back data for read operation. */
- if (!write) {
- /* Serial Interface : reg363_362[11:0] */
- *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ);
- *((u16 *)pDataBuf) &= 0x0FFF;
- }
-
- return true;
-}
-
-void RF_WriteReg(struct net_device *dev, u8 offset, u16 data)
-{
- u16 reg = (data << 4) | (offset & 0x0f);
- HwHSSIThreeWire(dev, (u8 *)®, true);
-}
-
-u16 RF_ReadReg(struct net_device *dev, u8 offset)
-{
- u16 reg = offset & 0x0f;
- HwHSSIThreeWire(dev, (u8 *)®, false);
- return reg;
-}
-
-static u8 ReadBBPortUchar(struct net_device *dev, u32 addr)
-{
- PlatformIOWrite4Byte(dev, PhyAddr, addr & 0xffffff7f);
- return PlatformIORead1Byte(dev, PhyDataR);
-}
-
-/* by Owen on 04/07/14 for writing BB register successfully */
-static void WriteBBPortUchar(struct net_device *dev, u32 Data)
-{
- PlatformIOWrite4Byte(dev, PhyAddr, Data);
- ReadBBPortUchar(dev, Data);
-}
-
-/*
- * Description:
- * Perform Antenna settings with antenna diversity on 87SE.
- * Created by Roger, 2008.01.25.
- */
-bool SetAntennaConfig87SE(struct net_device *dev,
- u8 DefaultAnt, /* 0: Main, 1: Aux. */
- bool bAntDiversity) /* 1:Enable, 0: Disable. */
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bAntennaSwitched = true;
- /* 0x00 = disabled, 0x80 = enabled */
- u8 ant_diversity_offset = 0x00;
-
- /*
- * printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n",
- * DefaultAnt, bAntDiversity);
- */
-
- /* Threshold for antenna diversity. */
- write_phy_cck(dev, 0x0c, 0x09); /* Reg0c : 09 */
-
- if (bAntDiversity) /* Enable Antenna Diversity. */
- ant_diversity_offset = 0x80;
-
- if (DefaultAnt == 1) { /* aux Antenna */
- /* Mac register, aux antenna */
- write_nic_byte(dev, ANTSEL, 0x00);
-
- /* Config CCK RX antenna. */
- write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */
-
- /* Reg01 : 47 | ant_diversity_offset */
- write_phy_cck(dev, 0x01, 0x47|ant_diversity_offset);
-
- /* Config OFDM RX antenna. */
- write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */
- /* Reg18 : 32 */
- write_phy_ofdm(dev, 0x18, 0x32|ant_diversity_offset);
- } else { /* main Antenna */
- /* Mac register, main antenna */
- write_nic_byte(dev, ANTSEL, 0x03);
-
- /* Config CCK RX antenna. */
- write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */
- /* Reg01 : 47 */
- write_phy_cck(dev, 0x01, 0x47|ant_diversity_offset);
-
- /* Config OFDM RX antenna. */
- write_phy_ofdm(dev, 0x0D, 0x5c); /* Reg0d : 5c */
- /*Reg18 : 32 */
- write_phy_ofdm(dev, 0x18, 0x32|ant_diversity_offset);
- }
- priv->CurrAntennaIndex = DefaultAnt; /* Update default settings. */
- return bAntennaSwitched;
-}
-/*
- *--------------------------------------------------------------
- * Hardware Initialization.
- * the code is ported from Windows source code
- *--------------------------------------------------------------
- */
-
-static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
-{
-
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u32 i;
- u32 addr, data;
- u32 u4bRegOffset, u4bRegValue;
- u16 u4bRF23, u4bRF24;
- u8 u1b24E;
- int d_cut = 0;
-
-
-/*
- *===========================================================================
- * 87S_PCIE :: RADIOCFG.TXT
- *===========================================================================
- */
-
-
- /* Page1 : reg16-reg30 */
- RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); /* switch to page1 */
- u4bRF23 = RF_ReadReg(dev, 0x08); mdelay(1);
- u4bRF24 = RF_ReadReg(dev, 0x09); mdelay(1);
-
- if (u4bRF23 == 0x818 && u4bRF24 == 0x70C) {
- d_cut = 1;
- netdev_info(dev, "card type changed from C- to D-cut\n");
- }
-
- /* Page0 : reg0-reg15 */
-
- RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);/* 1 */
- RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1);
- RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);/* 2 */
- RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);/* 3 */
- RF_WriteReg(dev, 0x04, 0x0975); mdelay(1);
- RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1);
- RF_WriteReg(dev, 0x06, 0x0ae6); mdelay(1);
- RF_WriteReg(dev, 0x07, 0x00ca); mdelay(1);
- RF_WriteReg(dev, 0x08, 0x0e1c); mdelay(1);
- RF_WriteReg(dev, 0x09, 0x02f0); mdelay(1);
- RF_WriteReg(dev, 0x0a, 0x09d0); mdelay(1);
- RF_WriteReg(dev, 0x0b, 0x01ba); mdelay(1);
- RF_WriteReg(dev, 0x0c, 0x0640); mdelay(1);
- RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1);
- RF_WriteReg(dev, 0x0e, 0x0020); mdelay(1);
- RF_WriteReg(dev, 0x0f, 0x0990); mdelay(1);
-
- /* Page1 : reg16-reg30 */
- RF_WriteReg(dev, 0x00, 0x013f); mdelay(1);
- RF_WriteReg(dev, 0x03, 0x0806); mdelay(1);
- RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1);
- RF_WriteReg(dev, 0x05, 0x059b); mdelay(1);
- RF_WriteReg(dev, 0x06, 0x0081); mdelay(1);
- RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1);
-/*
- * Don't write RF23/RF24 to make a difference between 87S C cut and D cut.
- * asked by SD3 stevenl.
- */
- RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
- RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1);
-
- if (d_cut) {
- RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
- RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
- /* RX LO buffer */
- RF_WriteReg(dev, 0x0e, 0x0807); mdelay(1);
- } else {
- RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
- RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
- /* RX LO buffer */
- RF_WriteReg(dev, 0x0e, 0x0806); mdelay(1);
- }
-
- RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
- RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1); /* 6 */
- RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1);
- RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1);
-
- for (i = 0; i <= 36; i++) {
- RF_WriteReg(dev, 0x01, i); mdelay(1);
- RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
- }
-
- RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /* 203, 343 */
- RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); /* 400 */
- /* switch to reg16-reg30, and HSSI disable 137 */
- RF_WriteReg(dev, 0x00, 0x0137); mdelay(1);
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- /* Z4 synthesizer loop filter setting, 392 */
- RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- /* switch to reg0-reg15, and HSSI disable */
- RF_WriteReg(dev, 0x00, 0x0037); mdelay(1);
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- /* CBC on, Tx Rx disable, High gain */
- RF_WriteReg(dev, 0x04, 0x0160); mdelay(1);
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- /* Z4 setted channel 1 */
- RF_WriteReg(dev, 0x07, 0x0080); mdelay(1);
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- RF_WriteReg(dev, 0x02, 0x088D); mdelay(1); /* LC calibration */
- mdelay(200); /* Deay 200 ms. */ /* 0xfd */
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- /* switch to reg16-reg30 137, and HSSI disable 137 */
- RF_WriteReg(dev, 0x00, 0x0137); mdelay(1);
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- RF_WriteReg(dev, 0x07, 0x0000); mdelay(1);
- RF_WriteReg(dev, 0x07, 0x0180); mdelay(1);
- RF_WriteReg(dev, 0x07, 0x0220); mdelay(1);
- RF_WriteReg(dev, 0x07, 0x03E0); mdelay(1);
-
- /* DAC calibration off 20070702 */
- RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1);
- RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
- /* For crystal calibration, added by Roger, 2007.12.11. */
- if (priv->bXtalCalibration) { /* reg 30. */
- /*
- * enable crystal calibration.
- * RF Reg[30], (1)Xin:[12:9], Xout:[8:5], addr[4:0].
- * (2)PA Pwr delay timer[15:14], default: 2.4us,
- * set BIT15=0
- * (3)RF signal on/off when calibration[13], default: on,
- * set BIT13=0.
- * So we should minus 4 BITs offset.
- */
- RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) |
- (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1);
- netdev_info(dev, "ZEBRA_Config_85BASIC_HardCode(): (%02x)\n",
- (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) |
- BIT11 | BIT9);
- } else {
- /* using default value. Xin=6, Xout=6. */
- RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
- }
- /* switch to reg0-reg15, and HSSI enable */
- RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1);
- /* Rx BB start calibration, 00c//+edward */
- RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1);
- /* temperature meter off */
- RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);
- RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); /* Rx mode */
- mdelay(10); /* Deay 10 ms.*/ /* 0xfe */
- mdelay(10); /* Deay 10 ms.*/ /* 0xfe */
- mdelay(10); /* Deay 10 ms.*/ /* 0xfe */
- /* Rx mode*/ /*+edward */
- RF_WriteReg(dev, 0x00, 0x0197); mdelay(1);
- /* Rx mode*/ /*+edward */
- RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1);
- /* Rx mode*/ /*+edward */
- RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);
- /* Rx mode*/ /*+edward */
- RF_WriteReg(dev, 0x01, 0x0000); mdelay(1);
- /* Rx mode*/ /*+edward */
- RF_WriteReg(dev, 0x02, 0x0000); mdelay(1);
- /* power save parameters. */
- u1b24E = read_nic_byte(dev, 0x24E);
- write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6))));
-
- /*======================================================================
- *
- *======================================================================
- * CCKCONF.TXT
- *======================================================================
- *
- * [POWER SAVE] Power Saving Parameters by jong. 2007-11-27
- * CCK reg0x00[7]=1'b1 :power saving for TX (default)
- * CCK reg0x00[6]=1'b1: power saving for RX (default)
- * CCK reg0x06[4]=1'b1: turn off channel estimation related
- * circuits if not doing channel estimation.
- * CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1
- * CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0
- */
-
- write_phy_cck(dev, 0x00, 0xc8);
- write_phy_cck(dev, 0x06, 0x1c);
- write_phy_cck(dev, 0x10, 0x78);
- write_phy_cck(dev, 0x2e, 0xd0);
- write_phy_cck(dev, 0x2f, 0x06);
- write_phy_cck(dev, 0x01, 0x46);
-
- /* power control */
- write_nic_byte(dev, CCK_TXAGC, 0x10);
- write_nic_byte(dev, OFDM_TXAGC, 0x1B);
- write_nic_byte(dev, ANTSEL, 0x03);
-
-
-
- /*
- *======================================================================
- * AGC.txt
- *======================================================================
- */
-
- write_phy_ofdm(dev, 0x00, 0x12);
-
- for (i = 0; i < 128; i++) {
-
- data = ZEBRA_AGC[i+1];
- data = data << 8;
- data = data | 0x0000008F;
-
- addr = i + 0x80; /* enable writing AGC table */
- addr = addr << 8;
- addr = addr | 0x0000008E;
-
- WriteBBPortUchar(dev, data);
- WriteBBPortUchar(dev, addr);
- WriteBBPortUchar(dev, 0x0000008E);
- }
-
- PlatformIOWrite4Byte(dev, PhyAddr, 0x00001080); /* Annie, 2006-05-05 */
-
- /*
- *======================================================================
- *
- *======================================================================
- * OFDMCONF.TXT
- *======================================================================
- */
-
- for (i = 0; i < 60; i++) {
- u4bRegOffset = i;
- u4bRegValue = OFDM_CONFIG[i];
-
- WriteBBPortUchar(dev,
- (0x00000080 |
- (u4bRegOffset & 0x7f) |
- ((u4bRegValue & 0xff) << 8)));
- }
-
- /*
- *======================================================================
- * by amy for antenna
- *======================================================================
- */
- /*
- * Config Sw/Hw Combinational Antenna Diversity. Added by Roger,
- * 2008.02.26.
- */
- SetAntennaConfig87SE(dev, priv->bDefaultAntenna1,
- priv->bSwAntennaDiverity);
-}
-
-
-void UpdateInitialGain(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- /* lzm add 080826 */
- if (priv->eRFPowerState != RF_ON) {
- /* Don't access BB/RF under disable PLL situation.
- * RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain -
- * pHalData->eRFPowerState!=RF_ON\n"));
- * Back to the original state
- */
- priv->InitialGain = priv->InitialGainBackUp;
- return;
- }
-
- switch (priv->InitialGain) {
- case 1: /* m861dBm */
- write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
- break;
-
- case 2: /* m862dBm */
- write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
- break;
-
- case 3: /* m863dBm */
- write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
- break;
-
- case 4: /* m864dBm */
- write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
- break;
-
- case 5: /* m82dBm */
- write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
- break;
-
- case 6: /* m78dBm */
- write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
- break;
-
- case 7: /* m74dBm */
- write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
- break;
-
- case 8:
- write_phy_ofdm(dev, 0x17, 0x66); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
- break;
-
- default: /* MP */
- write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
- break;
- }
-}
-/*
- * Description:
- * Tx Power tracking mechanism routine on 87SE.
- * Created by Roger, 2007.12.11.
- */
-static void InitTxPwrTracking87SE(struct net_device *dev)
-{
- u32 u4bRfReg;
-
- u4bRfReg = RF_ReadReg(dev, 0x02);
-
- /* Enable Thermal meter indication. */
- RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1);
-}
-
-static void PhyConfig8185(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- write_nic_dword(dev, RCR, priv->ReceiveConfig);
- priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03;
- /* RF config */
- ZEBRA_Config_85BASIC_HardCode(dev);
- /* Set default initial gain state to 4, approved by SD3 DZ, by Bruce,
- * 2007-06-06.
- */
- if (priv->bDigMechanism) {
- if (priv->InitialGain == 0)
- priv->InitialGain = 4;
- }
-
- /*
- * Enable thermal meter indication to implement TxPower tracking
- * on 87SE. We initialize thermal meter here to avoid unsuccessful
- * configuration. Added by Roger, 2007.12.11.
- */
- if (priv->bTxPowerTrack)
- InitTxPwrTracking87SE(dev);
-
- priv->InitialGainBackUp = priv->InitialGain;
- UpdateInitialGain(dev);
-
- return;
-}
-
-static void HwConfigureRTL8185(struct net_device *dev)
-{
- /*
- * RTL8185_TODO: Determine Retrylimit, TxAGC,
- * AutoRateFallback control.
- */
- u8 bUNIVERSAL_CONTROL_RL = 0;
- u8 bUNIVERSAL_CONTROL_AGC = 1;
- u8 bUNIVERSAL_CONTROL_ANT = 1;
- u8 bAUTO_RATE_FALLBACK_CTL = 1;
- u8 val8;
- write_nic_word(dev, BRSR, 0x0fff);
- /* Retry limit */
- val8 = read_nic_byte(dev, CW_CONF);
-
- if (bUNIVERSAL_CONTROL_RL)
- val8 = val8 & 0xfd;
- else
- val8 = val8 | 0x02;
-
- write_nic_byte(dev, CW_CONF, val8);
-
- /* Tx AGC */
- val8 = read_nic_byte(dev, TXAGC_CTL);
- if (bUNIVERSAL_CONTROL_AGC) {
- write_nic_byte(dev, CCK_TXAGC, 128);
- write_nic_byte(dev, OFDM_TXAGC, 128);
- val8 = val8 & 0xfe;
- } else {
- val8 = val8 | 0x01;
- }
-
-
- write_nic_byte(dev, TXAGC_CTL, val8);
-
- /* Tx Antenna including Feedback control */
- val8 = read_nic_byte(dev, TXAGC_CTL);
-
- if (bUNIVERSAL_CONTROL_ANT) {
- write_nic_byte(dev, ANTSEL, 0x00);
- val8 = val8 & 0xfd;
- } else {
- val8 = val8 & (val8|0x02); /* xiong-2006-11-15 */
- }
-
- write_nic_byte(dev, TXAGC_CTL, val8);
-
- /* Auto Rate fallback control */
- val8 = read_nic_byte(dev, RATE_FALLBACK);
- val8 &= 0x7c;
- if (bAUTO_RATE_FALLBACK_CTL) {
- val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
-
- /* <RJ_TODO_8185B> We shall set up the ARFR according
- * to user's setting.
- */
- PlatformIOWrite2Byte(dev, ARFR, 0x0fff); /* set 1M ~ 54Mbps. */
- }
- write_nic_byte(dev, RATE_FALLBACK, val8);
-}
-
-static void MacConfig_85BASIC_HardCode(struct net_device *dev)
-{
- /*
- *======================================================================
- * MACREG.TXT
- *======================================================================
- */
- int nLinesRead = 0;
- u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0;
- int i;
-
- nLinesRead = sizeof(MAC_REG_TABLE)/2;
-
- for (i = 0; i < nLinesRead; i++) { /* nLinesRead=101 */
- u4bRegOffset = MAC_REG_TABLE[i][0];
- u4bRegValue = MAC_REG_TABLE[i][1];
-
- if (u4bRegOffset == 0x5e)
- u4bPageIndex = u4bRegValue;
- else
- u4bRegOffset |= (u4bPageIndex << 8);
-
- write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
- }
- /* ================================================================= */
-}
-
-static void MacConfig_85BASIC(struct net_device *dev)
-{
-
- u8 u1DA;
- MacConfig_85BASIC_HardCode(dev);
-
- /* ================================================================= */
-
- /* Follow TID_AC_MAP of WMac. */
- write_nic_word(dev, TID_AC_MAP, 0xfa50);
-
- /* Interrupt Migration, Jong suggested we use set 0x0000 first,
- * 2005.12.14, by rcnjko.
- */
- write_nic_word(dev, IntMig, 0x0000);
-
- /* Prevent TPC to cause CRC error. Added by Annie, 2006-06-10. */
- PlatformIOWrite4Byte(dev, 0x1F0, 0x00000000);
- PlatformIOWrite4Byte(dev, 0x1F4, 0x00000000);
- PlatformIOWrite1Byte(dev, 0x1F8, 0x00);
-
- /* Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. */
-
- /*
- * power save parameter based on
- * "87SE power save parameters 20071127.doc", as follow.
- */
-
- /* Enable DA10 TX power saving */
- u1DA = read_nic_byte(dev, PHYPR);
- write_nic_byte(dev, PHYPR, (u1DA | BIT2));
-
- /* POWER: */
- write_nic_word(dev, 0x360, 0x1000);
- write_nic_word(dev, 0x362, 0x1000);
-
- /* AFE. */
- write_nic_word(dev, 0x370, 0x0560);
- write_nic_word(dev, 0x372, 0x0560);
- write_nic_word(dev, 0x374, 0x0DA4);
- write_nic_word(dev, 0x376, 0x0DA4);
- write_nic_word(dev, 0x378, 0x0560);
- write_nic_word(dev, 0x37A, 0x0560);
- write_nic_word(dev, 0x37C, 0x00EC);
- write_nic_word(dev, 0x37E, 0x00EC); /* +edward */
- write_nic_byte(dev, 0x24E, 0x01);
-}
-
-static u8 GetSupportedWirelessMode8185(struct net_device *dev)
-{
- return WIRELESS_MODE_B | WIRELESS_MODE_G;
-}
-
-static void
-ActUpdateChannelAccessSetting(struct net_device *dev,
- enum wireless_mode mode,
- struct chnl_access_setting *chnl_access_setting)
-{
- AC_CODING eACI;
-
- /*
- * <RJ_TODO_8185B>
- * TODO: We still don't know how to set up these registers,
- * just follow WMAC to verify 8185B FPAG.
- *
- * <RJ_TODO_8185B>
- * Jong said CWmin/CWmax register are not functional in 8185B,
- * so we shall fill channel access realted register into AC
- * parameter registers,
- * even in nQBss.
- */
-
- /* Suggested by Jong, 2005.12.08. */
- chnl_access_setting->sifs_timer = 0x22;
- chnl_access_setting->difs_timer = 0x1C; /* 2006.06.02, by rcnjko. */
- chnl_access_setting->slot_time_timer = 9; /* 2006.06.02, by rcnjko. */
- /*
- * Suggested by wcchu, it is the default value of EIFS register,
- * 2005.12.08.
- */
- chnl_access_setting->eifs_timer = 0x5B;
- chnl_access_setting->cwmin_index = 3; /* 2006.06.02, by rcnjko. */
- chnl_access_setting->cwmax_index = 7; /* 2006.06.02, by rcnjko. */
-
- write_nic_byte(dev, SIFS, chnl_access_setting->sifs_timer);
- /*
- * Rewrited from directly use PlatformEFIOWrite1Byte(),
- * by Annie, 2006-03-29.
- */
- write_nic_byte(dev, SLOT, chnl_access_setting->slot_time_timer);
-
- write_nic_byte(dev, EIFS, chnl_access_setting->eifs_timer);
-
- /*
- * <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS
- * register, 2005.12.08.
- */
- write_nic_byte(dev, AckTimeOutReg, 0x5B);
-
- for (eACI = 0; eACI < AC_MAX; eACI++)
- write_nic_byte(dev, ACM_CONTROL, 0);
-}
-
-static void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
- u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev);
-
- if ((btWirelessMode & btSupportedWirelessMode) == 0) {
- /*
- * Don't switch to unsupported wireless mode, 2006.02.15,
- * by rcnjko.
- */
- DMESGW("ActSetWirelessMode8185(): WirelessMode(%d) is not supported (%d)!\n",
- btWirelessMode, btSupportedWirelessMode);
- return;
- }
-
- /* 1. Assign wireless mode to switch if necessary. */
- if (btWirelessMode == WIRELESS_MODE_AUTO) {
- if ((btSupportedWirelessMode & WIRELESS_MODE_A)) {
- btWirelessMode = WIRELESS_MODE_A;
- } else if (btSupportedWirelessMode & WIRELESS_MODE_G) {
- btWirelessMode = WIRELESS_MODE_G;
-
- } else if ((btSupportedWirelessMode & WIRELESS_MODE_B)) {
- btWirelessMode = WIRELESS_MODE_B;
- } else {
- DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n",
- btSupportedWirelessMode);
- btWirelessMode = WIRELESS_MODE_B;
- }
- }
-
- /*
- * 2. Swtich band: RF or BB specific actions,
- * for example, refresh tables in omc8255, or change initial gain if
- * necessary. Nothing to do for Zebra to switch band. Update current
- * wireless mode if we switch to specified band successfully.
- */
-
- ieee->mode = (enum wireless_mode)btWirelessMode;
-
- /* 3. Change related setting. */
- if (ieee->mode == WIRELESS_MODE_A)
- DMESG("WIRELESS_MODE_A\n");
- else if (ieee->mode == WIRELESS_MODE_B)
- DMESG("WIRELESS_MODE_B\n");
- else if (ieee->mode == WIRELESS_MODE_G)
- DMESG("WIRELESS_MODE_G\n");
-
- ActUpdateChannelAccessSetting(dev, ieee->mode,
- &priv->ChannelAccessSetting);
-}
-
-void rtl8185b_irq_enable(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- priv->irq_enabled = 1;
- write_nic_dword(dev, IMR, priv->IntrMask);
-}
-
-static void MgntDisconnectIBSS(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u8 i;
-
- for (i = 0; i < 6; i++)
- priv->ieee80211->current_network.bssid[i] = 0x55;
-
-
-
- priv->ieee80211->state = IEEE80211_NOLINK;
- /*
- * Stop Beacon.
- *
- * Vista add a Adhoc profile, HW radio off until
- * OID_DOT11_RESET_REQUEST Driver would set MSR=NO_LINK,
- * then HW Radio ON, MgntQueue Stuck. Because Bcn DMA isn't
- * complete, mgnt queue would stuck until Bcn packet send.
- *
- * Disable Beacon Queue Own bit, suggested by jong
- */
- ieee80211_stop_send_beacons(priv->ieee80211);
-
- priv->ieee80211->link_change(dev);
- notify_wx_assoc_event(priv->ieee80211);
-}
-
-static void MlmeDisassociateRequest(struct net_device *dev, u8 *asSta, u8 asRsn)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u8 i;
-
- SendDisassociation(priv->ieee80211, asSta, asRsn);
-
- if (memcmp(priv->ieee80211->current_network.bssid, asSta, 6) == 0) {
- /* ShuChen TODO: change media status. */
-
- for (i = 0; i < 6; i++)
- priv->ieee80211->current_network.bssid[i] = 0x22;
-
- ieee80211_disassociate(priv->ieee80211);
- }
-}
-
-static void MgntDisconnectAP(struct net_device *dev, u8 asRsn)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- /*
- * Commented out by rcnjko, 2005.01.27:
- * I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
- *
- * 2004/09/15, kcwu, the key should be cleared, or the new
- * handshaking will not success
- *
- * In WPA WPA2 need to Clear all key ... because new key will set
- * after new handshaking. 2004.10.11, by rcnjko.
- */
- MlmeDisassociateRequest(dev, priv->ieee80211->current_network.bssid,
- asRsn);
-
- priv->ieee80211->state = IEEE80211_NOLINK;
-}
-
-static bool MgntDisconnect(struct net_device *dev, u8 asRsn)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- /*
- * Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
- */
-
- if (IS_DOT11D_ENABLE(priv->ieee80211))
- Dot11d_Reset(priv->ieee80211);
- /* In adhoc mode, update beacon frame. */
- if (priv->ieee80211->state == IEEE80211_LINKED) {
- if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- MgntDisconnectIBSS(dev);
-
- if (priv->ieee80211->iw_mode == IW_MODE_INFRA) {
- /*
- * We clear key here instead of MgntDisconnectAP()
- * because that MgntActSet_802_11_DISASSOCIATE()
- * is an interface called by OS, e.g.
- * OID_802_11_DISASSOCIATE in Windows while as
- * MgntDisconnectAP() is used to handle
- * disassociation related things to AP, e.g. send
- * Disassoc frame to AP. 2005.01.27, by rcnjko.
- */
- MgntDisconnectAP(dev, asRsn);
- }
- /* Indicate Disconnect, 2005.02.23, by rcnjko. */
- }
- return true;
-}
-/*
- * Description:
- * Chang RF Power State.
- * Note that, only MgntActSet_RF_State() is allowed to set
- * HW_VAR_RF_STATE.
- *
- * Assumption:
- * PASSIVE LEVEL.
- */
-static bool SetRFPowerState(struct net_device *dev,
- enum rt_rf_power_state eRFPowerState)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bResult = false;
-
- if (eRFPowerState == priv->eRFPowerState)
- return bResult;
-
- bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
-
- return bResult;
-}
-
-bool MgntActSet_RF_State(struct net_device *dev, enum rt_rf_power_state StateToSet,
- u32 ChangeSource)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bActionAllowed = false;
- bool bConnectBySSID = false;
- enum rt_rf_power_state rtState;
- u16 RFWaitCounter = 0;
- unsigned long flag;
- /*
- * Prevent the race condition of RF state change. By Bruce,
- * 2007-11-28. Only one thread can change the RF state at one time,
- * and others should wait to be executed.
- */
- while (true) {
- spin_lock_irqsave(&priv->rf_ps_lock, flag);
- if (priv->RFChangeInProgress) {
- spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
- /* Set RF after the previous action is done. */
- while (priv->RFChangeInProgress) {
- RFWaitCounter++;
- udelay(1000); /* 1 ms */
-
- /*
- * Wait too long, return FALSE to avoid
- * to be stuck here.
- */
- if (RFWaitCounter > 1000) { /* 1sec */
- netdev_info(dev, "MgntActSet_RF_State(): Wait too long to set RF\n");
- /* TODO: Reset RF state? */
- return false;
- }
- }
- } else {
- priv->RFChangeInProgress = true;
- spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
- break;
- }
- }
- rtState = priv->eRFPowerState;
-
- switch (StateToSet) {
- case RF_ON:
- /*
- * Turn On RF no matter the IPS setting because we need to
- * update the RF state to Ndis under Vista, or the Windows
- * does not allow the driver to perform site survey any
- * more. By Bruce, 2007-10-02.
- */
- priv->RfOffReason &= (~ChangeSource);
-
- if (!priv->RfOffReason) {
- priv->RfOffReason = 0;
- bActionAllowed = true;
-
- if (rtState == RF_OFF &&
- ChangeSource >= RF_CHANGE_BY_HW)
- bConnectBySSID = true;
- }
- break;
-
- case RF_OFF:
- /* 070125, rcnjko: we always keep connected in AP mode. */
-
- if (priv->RfOffReason > RF_CHANGE_BY_IPS) {
- /*
- * 060808, Annie:
- * Disconnect to current BSS when radio off.
- * Asked by QuanTa.
- *
- * Calling MgntDisconnect() instead of
- * MgntActSet_802_11_DISASSOCIATE(), because
- * we do NOT need to set ssid to dummy ones.
- */
- MgntDisconnect(dev, disas_lv_ss);
- /*
- * Clear content of bssDesc[] and bssDesc4Query[]
- * to avoid reporting old bss to UI.
- */
- }
-
- priv->RfOffReason |= ChangeSource;
- bActionAllowed = true;
- break;
- case RF_SLEEP:
- priv->RfOffReason |= ChangeSource;
- bActionAllowed = true;
- break;
- default:
- break;
- }
-
- if (bActionAllowed) {
- /* Config HW to the specified mode. */
- SetRFPowerState(dev, StateToSet);
- }
-
- /* Release RF spinlock */
- spin_lock_irqsave(&priv->rf_ps_lock, flag);
- priv->RFChangeInProgress = false;
- spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
- return bActionAllowed;
-}
-
-static void InactivePowerSave(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- /*
- * This flag "bSwRfProcessing", indicates the status of IPS
- * procedure, should be set if the IPS workitem is really
- * scheduled. The old code, sets this flag before scheduling the
- * IPS workitem and however, at the same time the previous IPS
- * workitem did not end yet, fails to schedule the current
- * workitem. Thus, bSwRfProcessing blocks the IPS procedure of
- * switching RF.
- */
- priv->bSwRfProcessing = true;
-
- MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
-
- /*
- * To solve CAM values miss in RF OFF, rewrite CAM values after
- * RF ON. By Bruce, 2007-09-20.
- */
-
- priv->bSwRfProcessing = false;
-}
-
-/*
- * Description:
- * Enter the inactive power save mode. RF will be off
- */
-void IPSEnter(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- enum rt_rf_power_state rtState;
- if (priv->bInactivePs) {
- rtState = priv->eRFPowerState;
-
- /*
- * Do not enter IPS in the following conditions:
- * (1) RF is already OFF or
- * Sleep (2) bSwRfProcessing (indicates the IPS is still
- * under going) (3) Connected (only disconnected can
- * trigger IPS)(4) IBSS (send Beacon)
- * (5) AP mode (send Beacon)
- */
- if (rtState == RF_ON && !priv->bSwRfProcessing
- && (priv->ieee80211->state != IEEE80211_LINKED)) {
- priv->eInactivePowerState = RF_OFF;
- InactivePowerSave(dev);
- }
- }
-}
-void IPSLeave(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- enum rt_rf_power_state rtState;
- if (priv->bInactivePs) {
- rtState = priv->eRFPowerState;
- if ((rtState == RF_OFF || rtState == RF_SLEEP) &&
- !priv->bSwRfProcessing
- && priv->RfOffReason <= RF_CHANGE_BY_IPS) {
- priv->eInactivePowerState = RF_ON;
- InactivePowerSave(dev);
- }
- }
-}
-
-void rtl8185b_adapter_start(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
-
- u8 SupportedWirelessMode;
- u8 InitWirelessMode;
- u8 bInvalidWirelessMode = 0;
- u8 tmpu8;
- u8 btCR9346;
- u8 TmpU1b;
- u8 btPSR;
-
- write_nic_byte(dev, 0x24e, (BIT5|BIT6|BIT0));
- rtl8180_reset(dev);
-
- priv->dma_poll_mask = 0;
- priv->dma_poll_stop_mask = 0;
-
- HwConfigureRTL8185(dev);
- write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
- write_nic_word(dev, MAC4, ((u32 *)dev->dev_addr)[1] & 0xffff);
- /* default network type to 'No Link' */
- write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3);
- write_nic_word(dev, BcnItv, 100);
- write_nic_word(dev, AtimWnd, 2);
- PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
- write_nic_byte(dev, WPA_CONFIG, 0);
- MacConfig_85BASIC(dev);
- /* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07,
- * by rcnjko.
- */
- /* BT_DEMO_BOARD type */
- PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a);
-
- /*
- *---------------------------------------------------------------------
- * Set up PHY related.
- *---------------------------------------------------------------------
- */
- /* Enable Config3.PARAM_En to revise AnaaParm. */
- write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */
- tmpu8 = read_nic_byte(dev, CONFIG3);
- write_nic_byte(dev, CONFIG3, (tmpu8 | CONFIG3_PARM_En));
- /* Turn on Analog power. */
- /* Asked for by William, otherwise, MAC 3-wire can't work,
- * 2006.06.27, by rcnjko.
- */
- write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
- write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
- write_nic_word(dev, ANAPARAM3, 0x0010);
-
- write_nic_byte(dev, CONFIG3, tmpu8);
- write_nic_byte(dev, CR9346, 0x00);
- /* enable EEM0 and EEM1 in 9346CR */
- btCR9346 = read_nic_byte(dev, CR9346);
- write_nic_byte(dev, CR9346, (btCR9346 | 0xC0));
-
- /* B cut use LED1 to control HW RF on/off */
- TmpU1b = read_nic_byte(dev, CONFIG5);
- TmpU1b = TmpU1b & ~BIT3;
- write_nic_byte(dev, CONFIG5, TmpU1b);
-
- /* disable EEM0 and EEM1 in 9346CR */
- btCR9346 &= ~(0xC0);
- write_nic_byte(dev, CR9346, btCR9346);
-
- /* Enable Led (suggested by Jong) */
- /* B-cut RF Radio on/off 5e[3]=0 */
- btPSR = read_nic_byte(dev, PSR);
- write_nic_byte(dev, PSR, (btPSR | BIT3));
- /* setup initial timing for RFE. */
- write_nic_word(dev, RFPinsOutput, 0x0480);
- SetOutputEnableOfRfPins(dev);
- write_nic_word(dev, RFPinsSelect, 0x2488);
-
- /* PHY config. */
- PhyConfig8185(dev);
-
- /*
- * We assume RegWirelessMode has already been initialized before,
- * however, we has to validate the wireless mode here and provide a
- * reasonable initialized value if necessary. 2005.01.13,
- * by rcnjko.
- */
- SupportedWirelessMode = GetSupportedWirelessMode8185(dev);
- if ((ieee->mode != WIRELESS_MODE_B) &&
- (ieee->mode != WIRELESS_MODE_G) &&
- (ieee->mode != WIRELESS_MODE_A) &&
- (ieee->mode != WIRELESS_MODE_AUTO)) {
- /* It should be one of B, G, A, or AUTO. */
- bInvalidWirelessMode = 1;
- } else {
- /* One of B, G, A, or AUTO. */
- /* Check if the wireless mode is supported by RF. */
- if ((ieee->mode != WIRELESS_MODE_AUTO) &&
- (ieee->mode & SupportedWirelessMode) == 0) {
- bInvalidWirelessMode = 1;
- }
- }
-
- if (bInvalidWirelessMode || ieee->mode == WIRELESS_MODE_AUTO) {
- /* Auto or other invalid value. */
- /* Assigne a wireless mode to initialize. */
- if ((SupportedWirelessMode & WIRELESS_MODE_A)) {
- InitWirelessMode = WIRELESS_MODE_A;
- } else if ((SupportedWirelessMode & WIRELESS_MODE_G)) {
- InitWirelessMode = WIRELESS_MODE_G;
- } else if ((SupportedWirelessMode & WIRELESS_MODE_B)) {
- InitWirelessMode = WIRELESS_MODE_B;
- } else {
- DMESGW("InitializeAdapter8185(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
- SupportedWirelessMode);
- InitWirelessMode = WIRELESS_MODE_B;
- }
-
- /* Initialize RegWirelessMode if it is not a valid one. */
- if (bInvalidWirelessMode)
- ieee->mode = (enum wireless_mode)InitWirelessMode;
-
- } else {
- /* One of B, G, A. */
- InitWirelessMode = ieee->mode;
- }
- priv->eRFPowerState = RF_OFF;
- priv->RfOffReason = 0;
- {
- MgntActSet_RF_State(dev, RF_ON, 0);
- }
- /*
- * If inactive power mode is enabled, disable rf while in
- * disconnected state.
- */
- if (priv->bInactivePs)
- MgntActSet_RF_State(dev , RF_OFF, RF_CHANGE_BY_IPS);
-
- ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
-
- /* ----------------------------------------------------------------- */
-
- rtl8185b_irq_enable(dev);
-
- netif_start_queue(dev);
-}
-
-void rtl8185b_rx_enable(struct net_device *dev)
-{
- u8 cmd;
- /* for now we accept data, management & ctl frame*/
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-
- if (dev->flags & IFF_PROMISC)
- DMESG("NIC in promisc mode");
-
- if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || dev->flags &
- IFF_PROMISC) {
- priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM);
- priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
- }
-
- if (priv->ieee80211->iw_mode == IW_MODE_MONITOR)
- priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF |
- RCR_APWRMGT | RCR_AICV;
-
-
- if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
- priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACRC32;
-
- write_nic_dword(dev, RCR, priv->ReceiveConfig);
-
- fix_rx_fifo(dev);
-
- cmd = read_nic_byte(dev, CMD);
- write_nic_byte(dev, CMD, cmd | (1<<CMD_RX_ENABLE_SHIFT));
-
-}
-
-void rtl8185b_tx_enable(struct net_device *dev)
-{
- u8 cmd;
- u8 byte;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- write_nic_dword(dev, TCR, priv->TransmitConfig);
- byte = read_nic_byte(dev, MSR);
- byte |= MSR_LINK_ENEDCA;
- write_nic_byte(dev, MSR, byte);
-
- fix_tx_fifo(dev);
-
- cmd = read_nic_byte(dev, CMD);
- write_nic_byte(dev, CMD, cmd | (1<<CMD_TX_ENABLE_SHIFT));
-}
-
void nat25_db_cleanup(struct adapter *priv)
{
int i;
+
spin_lock_bh(&priv->br_ext_lock);
for (i = 0; i < NAT25_HASH_SIZE; i++) {
return res;
}
-u8 rtw_led_blink_cmd(struct adapter *padapter, struct LED_871x *pLed)
-{
- struct cmd_obj *pcmdobj;
- struct LedBlink_param *ledBlink_param;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
- u8 res = _SUCCESS;
-
-
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_led_blink_cmd\n"));
-
- pcmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (pcmdobj == NULL) {
- res = _FAIL;
- goto exit;
- }
-
- ledBlink_param = (struct LedBlink_param *)rtw_zmalloc(sizeof(struct LedBlink_param));
- if (ledBlink_param == NULL) {
- kfree(pcmdobj);
- res = _FAIL;
- goto exit;
- }
-
- ledBlink_param->pLed = pLed;
-
- init_h2fwcmd_w_parm_no_rsp(pcmdobj, ledBlink_param, GEN_CMD_CODE(_LedBlink));
- res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
-
-exit:
-
-
- return res;
-}
-
u8 rtw_set_csa_cmd(struct adapter *padapter, u8 new_ch_no)
{
struct cmd_obj *pcmdobj;
/* */
/* Description: */
/* Callback function of LED BlinkWorkItem. */
-/* We dispatch acture LED blink action according to LedStrategy. */
/* */
void BlinkWorkItemCallback(struct work_struct *work)
{
/*Description: */
/* Initialize an LED_871x object. */
-void InitLed871x(struct adapter *padapter, struct LED_871x *pLed, enum LED_PIN_871x LedPin)
+void InitLed871x(struct adapter *padapter, struct LED_871x *pLed)
{
pLed->padapter = padapter;
- pLed->LedPin = LedPin;
ResetLedStatus(pLed);
/* It toggle off LED and schedule corresponding timer if necessary. */
/* */
-static void SwLedBlink(struct LED_871x *pLed)
-{
- struct adapter *padapter = pLed->padapter;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- u8 bStopBlinking = false;
-
- /* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == RTW_LED_ON) {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- } else {
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
- /* Determine if we shall change LED state again. */
- pLed->BlinkTimes--;
- switch (pLed->CurrLedState) {
- case LED_BLINK_NORMAL:
- if (pLed->BlinkTimes == 0)
- bStopBlinking = true;
- break;
- case LED_BLINK_StartToBlink:
- if (check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE))
- bStopBlinking = true;
- if (check_fwstate(pmlmepriv, _FW_LINKED) &&
- (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
- bStopBlinking = true;
- else if (pLed->BlinkTimes == 0)
- bStopBlinking = true;
- break;
- case LED_BLINK_WPS:
- if (pLed->BlinkTimes == 0)
- bStopBlinking = true;
- break;
- default:
- bStopBlinking = true;
- break;
- }
-
- if (bStopBlinking) {
- /* if (padapter->pwrctrlpriv.cpwm >= PS_STATE_S2) */
- if (0) {
- SwLedOff(padapter, pLed);
- } else if ((check_fwstate(pmlmepriv, _FW_LINKED)) && (!pLed->bLedOn)) {
- SwLedOn(padapter, pLed);
- } else if ((check_fwstate(pmlmepriv, _FW_LINKED)) && pLed->bLedOn) {
- SwLedOff(padapter, pLed);
- }
- pLed->BlinkTimes = 0;
- pLed->bLedBlinkInProgress = false;
- } else {
- /* Assign LED state to toggle. */
- if (pLed->BlinkingLedState == RTW_LED_ON)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
-
- /* Schedule a timer to toggle LED state. */
- switch (pLed->CurrLedState) {
- case LED_BLINK_NORMAL:
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- break;
- case LED_BLINK_SLOWLY:
- case LED_BLINK_StartToBlink:
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- break;
- case LED_BLINK_WPS:
- if (pLed->BlinkingLedState == RTW_LED_ON)
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
- else
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
- break;
- default:
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- break;
- }
- }
-}
-
static void SwLedBlink1(struct LED_871x *pLed)
{
struct adapter *padapter = pLed->padapter;
}
pLed->BlinkTimes = 0;
pLed->bLedBlinkInProgress = false;
- } else {
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- break;
- case LED_BLINK_WPS:
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- break;
- case LED_BLINK_WPS_STOP: /* WPS success */
- if (pLed->BlinkingLedState == RTW_LED_ON)
- bStopBlinking = false;
- else
- bStopBlinking = true;
-
- if (bStopBlinking) {
- pLed->bLedLinkBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_NORMAL;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
-
- pLed->bLedWPSBlinkInProgress = false;
- } else {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
- }
- break;
- default:
- break;
- }
-}
-
-static void SwLedBlink2(struct LED_871x *pLed)
-{
- struct adapter *padapter = pLed->padapter;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- u8 bStopBlinking = false;
-
- /* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == RTW_LED_ON) {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- } else {
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
- switch (pLed->CurrLedState) {
- case LED_BLINK_SCAN:
- pLed->BlinkTimes--;
- if (pLed->BlinkTimes == 0)
- bStopBlinking = true;
- if (bStopBlinking) {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
- SwLedOff(padapter, pLed);
- } else if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("stop scan blink CurrLedState %d\n", pLed->CurrLedState));
-
- } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("stop scan blink CurrLedState %d\n", pLed->CurrLedState));
- }
- pLed->bLedScanBlinkInProgress = false;
- } else {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
- SwLedOff(padapter, pLed);
- } else {
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- }
- break;
- case LED_BLINK_TXRX:
- pLed->BlinkTimes--;
- if (pLed->BlinkTimes == 0)
- bStopBlinking = true;
- if (bStopBlinking) {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
- SwLedOff(padapter, pLed);
- } else if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("stop CurrLedState %d\n", pLed->CurrLedState));
- } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("stop CurrLedState %d\n", pLed->CurrLedState));
- }
- pLed->bLedBlinkInProgress = false;
- } else {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
- SwLedOff(padapter, pLed);
- } else {
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- }
- break;
- default:
- break;
- }
-}
-
-static void SwLedBlink3(struct LED_871x *pLed)
-{
- struct adapter *padapter = pLed->padapter;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- u8 bStopBlinking = false;
-
- /* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == RTW_LED_ON) {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- } else {
- if (pLed->CurrLedState != LED_BLINK_WPS_STOP)
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
- switch (pLed->CurrLedState) {
- case LED_BLINK_SCAN:
- pLed->BlinkTimes--;
- if (pLed->BlinkTimes == 0)
- bStopBlinking = true;
- if (bStopBlinking) {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
- SwLedOff(padapter, pLed);
- } else if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- if (!pLed->bLedOn)
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
- } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- if (pLed->bLedOn)
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
- }
- pLed->bLedScanBlinkInProgress = false;
- } else {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
- SwLedOff(padapter, pLed);
- } else {
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- }
- break;
- case LED_BLINK_TXRX:
- pLed->BlinkTimes--;
- if (pLed->BlinkTimes == 0)
- bStopBlinking = true;
- if (bStopBlinking) {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
- SwLedOff(padapter, pLed);
- } else if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- if (!pLed->bLedOn)
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
- } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
-
- if (pLed->bLedOn)
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
- }
- pLed->bLedBlinkInProgress = false;
- } else {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
- SwLedOff(padapter, pLed);
- } else {
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- }
- break;
- case LED_BLINK_WPS:
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- break;
- case LED_BLINK_WPS_STOP: /* WPS success */
- if (pLed->BlinkingLedState == RTW_LED_ON) {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
- bStopBlinking = false;
- } else {
- bStopBlinking = true;
- }
- if (bStopBlinking) {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
- SwLedOff(padapter, pLed);
- } else {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
- }
- pLed->bLedWPSBlinkInProgress = false;
- }
- break;
- default:
- break;
- }
-}
-
-static void SwLedBlink4(struct LED_871x *pLed)
-{
- struct adapter *padapter = pLed->padapter;
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct LED_871x *pLed1 = &(ledpriv->SwLed1);
- u8 bStopBlinking = false;
-
- /* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == RTW_LED_ON) {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- } else {
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
- if (!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN) {
- pLed1->BlinkingLedState = RTW_LED_OFF;
- pLed1->CurrLedState = RTW_LED_OFF;
- SwLedOff(padapter, pLed1);
- }
-
- switch (pLed->CurrLedState) {
- case LED_BLINK_SLOWLY:
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- break;
- case LED_BLINK_StartToBlink:
- if (pLed->bLedOn) {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- } else {
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- }
- break;
- case LED_BLINK_SCAN:
- pLed->BlinkTimes--;
- if (pLed->BlinkTimes == 0)
- bStopBlinking = false;
- if (bStopBlinking) {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) {
- SwLedOff(padapter, pLed);
- } else {
- pLed->bLedNoLinkBlinkInProgress = false;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- }
- pLed->bLedScanBlinkInProgress = false;
- } else {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) {
- SwLedOff(padapter, pLed);
- } else {
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- }
- break;
- case LED_BLINK_TXRX:
- pLed->BlinkTimes--;
- if (pLed->BlinkTimes == 0)
- bStopBlinking = true;
- if (bStopBlinking) {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) {
- SwLedOff(padapter, pLed);
- } else {
- pLed->bLedNoLinkBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- }
- pLed->bLedBlinkInProgress = false;
- } else {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) {
- SwLedOff(padapter, pLed);
- } else {
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- }
- break;
- case LED_BLINK_WPS:
- if (pLed->bLedOn) {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- } else {
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- }
- break;
- case LED_BLINK_WPS_STOP: /* WPS authentication fail */
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
-
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- break;
- case LED_BLINK_WPS_STOP_OVERLAP: /* WPS session overlap */
- pLed->BlinkTimes--;
- if (pLed->BlinkTimes == 0) {
- if (pLed->bLedOn)
- pLed->BlinkTimes = 1;
- else
- bStopBlinking = true;
- }
-
- if (bStopBlinking) {
- pLed->BlinkTimes = 10;
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
- } else {
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
-
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- }
- break;
- default:
- break;
- }
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("SwLedBlink4 CurrLedState %d\n", pLed->CurrLedState));
-}
-
-static void SwLedBlink5(struct LED_871x *pLed)
-{
- struct adapter *padapter = pLed->padapter;
- u8 bStopBlinking = false;
-
- /* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == RTW_LED_ON) {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- } else {
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
- switch (pLed->CurrLedState) {
- case LED_BLINK_SCAN:
- pLed->BlinkTimes--;
- if (pLed->BlinkTimes == 0)
- bStopBlinking = true;
-
- if (bStopBlinking) {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- if (pLed->bLedOn)
- SwLedOff(padapter, pLed);
- } else {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- if (!pLed->bLedOn)
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
-
- pLed->bLedScanBlinkInProgress = false;
- } else {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) {
- SwLedOff(padapter, pLed);
- } else {
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- }
- break;
- case LED_BLINK_TXRX:
- pLed->BlinkTimes--;
- if (pLed->BlinkTimes == 0)
- bStopBlinking = true;
-
- if (bStopBlinking) {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- if (pLed->bLedOn)
- SwLedOff(padapter, pLed);
- } else {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- if (!pLed->bLedOn)
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
-
- pLed->bLedBlinkInProgress = false;
- } else {
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) {
- SwLedOff(padapter, pLed);
- } else {
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- }
- break;
-
- default:
- break;
- }
-
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("SwLedBlink5 CurrLedState %d\n", pLed->CurrLedState));
-}
-
-static void SwLedBlink6(struct LED_871x *pLed)
-{
- struct adapter *padapter = pLed->padapter;
-
- /* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == RTW_LED_ON) {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- } else {
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("<==== blink6\n"));
-}
-
- /* ALPHA, added by chiyoko, 20090106 */
-static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAction)
-{
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct LED_871x *pLed = &(ledpriv->SwLed0);
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
-
- switch (LedAction) {
- case LED_CTL_POWER_ON:
- case LED_CTL_START_TO_LINK:
- case LED_CTL_NO_LINK:
- if (!pLed->bLedNoLinkBlinkInProgress) {
- if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- return;
- if (pLed->bLedLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = false;
- }
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
-
- pLed->bLedNoLinkBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- }
- break;
- case LED_CTL_LINK:
- if (!pLed->bLedLinkBlinkInProgress) {
- if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- return;
- if (pLed->bLedNoLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = false;
- }
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- pLed->bLedLinkBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_NORMAL;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
- }
- break;
- case LED_CTL_SITE_SURVEY:
- if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) {
- ;
- } else if (!pLed->bLedScanBlinkInProgress) {
- if (IS_LED_WPS_BLINKING(pLed))
- return;
- if (pLed->bLedNoLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = false;
- }
- if (pLed->bLedLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = false;
- }
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- pLed->bLedScanBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_SCAN;
- pLed->BlinkTimes = 24;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
- case LED_CTL_TX:
- case LED_CTL_RX:
- if (!pLed->bLedBlinkInProgress) {
- if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- return;
- if (pLed->bLedNoLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = false;
- }
- if (pLed->bLedLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = false;
- }
- pLed->bLedBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_TXRX;
- pLed->BlinkTimes = 2;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- break;
- case LED_CTL_START_WPS: /* wait until xinpin finish */
- case LED_CTL_START_WPS_BOTTON:
- if (!pLed->bLedWPSBlinkInProgress) {
- if (pLed->bLedNoLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = false;
- }
- if (pLed->bLedLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = false;
- }
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- if (pLed->bLedScanBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = false;
- }
- pLed->bLedWPSBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_WPS;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
- case LED_CTL_STOP_WPS:
- if (pLed->bLedNoLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = false;
- }
- if (pLed->bLedLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = false;
- }
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- if (pLed->bLedScanBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = false;
- }
- if (pLed->bLedWPSBlinkInProgress)
- _cancel_timer_ex(&(pLed->BlinkTimer));
- else
- pLed->bLedWPSBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_WPS_STOP;
- if (pLed->bLedOn) {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
- } else {
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), 0);
- }
- break;
- case LED_CTL_STOP_WPS_FAIL:
- if (pLed->bLedWPSBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = false;
- }
- pLed->bLedNoLinkBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- break;
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- if (pLed->bLedNoLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = false;
- }
- if (pLed->bLedLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = false;
- }
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- if (pLed->bLedWPSBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = false;
- }
- if (pLed->bLedScanBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = false;
- }
- SwLedOff(padapter, pLed);
- break;
- default:
- break;
- }
-
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Led %d\n", pLed->CurrLedState));
-}
-
- /* Arcadyan/Sitecom , added by chiyoko, 20090216 */
-static void SwLedControlMode2(struct adapter *padapter, enum LED_CTL_MODE LedAction)
-{
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct LED_871x *pLed = &(ledpriv->SwLed0);
-
- switch (LedAction) {
- case LED_CTL_SITE_SURVEY:
- if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
- } else if (!pLed->bLedScanBlinkInProgress) {
- if (IS_LED_WPS_BLINKING(pLed))
- return;
-
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- pLed->bLedScanBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_SCAN;
- pLed->BlinkTimes = 24;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
- case LED_CTL_TX:
- case LED_CTL_RX:
- if ((!pLed->bLedBlinkInProgress) && (check_fwstate(pmlmepriv, _FW_LINKED))) {
- if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- return;
- pLed->bLedBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_TXRX;
- pLed->BlinkTimes = 2;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- break;
- case LED_CTL_LINK:
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- if (pLed->bLedScanBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = false;
- }
- _set_timer(&(pLed->BlinkTimer), 0);
- break;
- case LED_CTL_START_WPS: /* wait until xinpin finish */
- case LED_CTL_START_WPS_BOTTON:
- if (!pLed->bLedWPSBlinkInProgress) {
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- if (pLed->bLedScanBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = false;
- }
- pLed->bLedWPSBlinkInProgress = true;
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), 0);
- }
- break;
- case LED_CTL_STOP_WPS:
- pLed->bLedWPSBlinkInProgress = false;
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
- SwLedOff(padapter, pLed);
- } else {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), 0);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
- }
- break;
- case LED_CTL_STOP_WPS_FAIL:
- pLed->bLedWPSBlinkInProgress = false;
- if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
- SwLedOff(padapter, pLed);
- } else {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), 0);
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
- }
- break;
- case LED_CTL_START_TO_LINK:
- case LED_CTL_NO_LINK:
- if (!IS_LED_BLINKING(pLed)) {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), 0);
- }
- break;
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- if (pLed->bLedScanBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = false;
- }
- if (pLed->bLedWPSBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = false;
- }
-
- _set_timer(&(pLed->BlinkTimer), 0);
- break;
- default:
- break;
- }
-
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
-}
-
- /* COREGA, added by chiyoko, 20090316 */
- static void SwLedControlMode3(struct adapter *padapter, enum LED_CTL_MODE LedAction)
-{
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct LED_871x *pLed = &(ledpriv->SwLed0);
-
- switch (LedAction) {
- case LED_CTL_SITE_SURVEY:
- if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
- } else if (!pLed->bLedScanBlinkInProgress) {
- if (IS_LED_WPS_BLINKING(pLed))
- return;
-
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- pLed->bLedScanBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_SCAN;
- pLed->BlinkTimes = 24;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
- case LED_CTL_TX:
- case LED_CTL_RX:
- if ((!pLed->bLedBlinkInProgress) && (check_fwstate(pmlmepriv, _FW_LINKED))) {
- if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- return;
- pLed->bLedBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_TXRX;
- pLed->BlinkTimes = 2;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- break;
- case LED_CTL_LINK:
- if (IS_LED_WPS_BLINKING(pLed))
- return;
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- if (pLed->bLedScanBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = false;
- }
-
- _set_timer(&(pLed->BlinkTimer), 0);
- break;
- case LED_CTL_START_WPS: /* wait until xinpin finish */
- case LED_CTL_START_WPS_BOTTON:
- if (!pLed->bLedWPSBlinkInProgress) {
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- if (pLed->bLedScanBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = false;
- }
- pLed->bLedWPSBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_WPS;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
- case LED_CTL_STOP_WPS:
- if (pLed->bLedWPSBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = false;
- } else {
- pLed->bLedWPSBlinkInProgress = true;
- }
-
- pLed->CurrLedState = LED_BLINK_WPS_STOP;
- if (pLed->bLedOn) {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
- } else {
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), 0);
- }
- break;
- case LED_CTL_STOP_WPS_FAIL:
- if (pLed->bLedWPSBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = false;
- }
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), 0);
- break;
- case LED_CTL_START_TO_LINK:
- case LED_CTL_NO_LINK:
- if (!IS_LED_BLINKING(pLed)) {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), 0);
- }
- break;
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- if (pLed->bLedScanBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = false;
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
}
- if (pLed->bLedWPSBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ break;
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ break;
+ case LED_BLINK_WPS_STOP: /* WPS success */
+ if (pLed->BlinkingLedState == RTW_LED_ON)
+ bStopBlinking = false;
+ else
+ bStopBlinking = true;
+
+ if (bStopBlinking) {
+ pLed->bLedLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
+
pLed->bLedWPSBlinkInProgress = false;
+ } else {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
}
-
- _set_timer(&(pLed->BlinkTimer), 0);
break;
default:
break;
}
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_,
- ("CurrLedState %d\n", pLed->CurrLedState));
}
- /* Edimax-Belkin, added by chiyoko, 20090413 */
-static void SwLedControlMode4(struct adapter *padapter, enum LED_CTL_MODE LedAction)
+ /* ALPHA, added by chiyoko, 20090106 */
+static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAction)
{
struct led_priv *ledpriv = &(padapter->ledpriv);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct LED_871x *pLed = &(ledpriv->SwLed0);
- struct LED_871x *pLed1 = &(ledpriv->SwLed1);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
switch (LedAction) {
+ case LED_CTL_POWER_ON:
case LED_CTL_START_TO_LINK:
- if (pLed1->bLedWPSBlinkInProgress) {
- pLed1->bLedWPSBlinkInProgress = false;
- _cancel_timer_ex(&(pLed1->BlinkTimer));
-
- pLed1->BlinkingLedState = RTW_LED_OFF;
- pLed1->CurrLedState = RTW_LED_OFF;
-
- if (pLed1->bLedOn)
- _set_timer(&(pLed->BlinkTimer), 0);
- }
-
- if (!pLed->bLedStartToLinkBlinkInProgress) {
+ case LED_CTL_NO_LINK:
+ if (!pLed->bLedNoLinkBlinkInProgress) {
if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
return;
- if (pLed->bLedBlinkInProgress) {
+ if (pLed->bLedLinkBlinkInProgress) {
_cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
+ pLed->bLedLinkBlinkInProgress = false;
}
- if (pLed->bLedNoLinkBlinkInProgress) {
+ if (pLed->bLedBlinkInProgress) {
_cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = false;
+ pLed->bLedBlinkInProgress = false;
}
- pLed->bLedStartToLinkBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_StartToBlink;
- if (pLed->bLedOn) {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- } else {
+ else
pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- }
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
}
break;
case LED_CTL_LINK:
- case LED_CTL_NO_LINK:
- /* LED1 settings */
- if (LedAction == LED_CTL_LINK) {
- if (pLed1->bLedWPSBlinkInProgress) {
- pLed1->bLedWPSBlinkInProgress = false;
- _cancel_timer_ex(&(pLed1->BlinkTimer));
-
- pLed1->BlinkingLedState = RTW_LED_OFF;
- pLed1->CurrLedState = RTW_LED_OFF;
-
- if (pLed1->bLedOn)
- _set_timer(&(pLed->BlinkTimer), 0);
- }
- }
-
- if (!pLed->bLedNoLinkBlinkInProgress) {
+ if (!pLed->bLedLinkBlinkInProgress) {
if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
return;
+ if (pLed->bLedNoLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
if (pLed->bLedBlinkInProgress) {
_cancel_timer_ex(&(pLed->BlinkTimer));
pLed->bLedBlinkInProgress = false;
}
-
- pLed->bLedNoLinkBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
+ pLed->bLedLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
if (pLed->bLedOn)
pLed->BlinkingLedState = RTW_LED_OFF;
else
pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
}
break;
case LED_CTL_SITE_SURVEY:
if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) {
+ ;
} else if (!pLed->bLedScanBlinkInProgress) {
if (IS_LED_WPS_BLINKING(pLed))
return;
-
if (pLed->bLedNoLinkBlinkInProgress) {
_cancel_timer_ex(&(pLed->BlinkTimer));
pLed->bLedNoLinkBlinkInProgress = false;
}
+ if (pLed->bLedLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
if (pLed->bLedBlinkInProgress) {
_cancel_timer_ex(&(pLed->BlinkTimer));
pLed->bLedBlinkInProgress = false;
else
pLed->BlinkingLedState = RTW_LED_ON;
_set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
+ }
break;
case LED_CTL_TX:
case LED_CTL_RX:
_cancel_timer_ex(&(pLed->BlinkTimer));
pLed->bLedNoLinkBlinkInProgress = false;
}
+ if (pLed->bLedLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
pLed->bLedBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_TXRX;
pLed->BlinkTimes = 2;
break;
case LED_CTL_START_WPS: /* wait until xinpin finish */
case LED_CTL_START_WPS_BOTTON:
- if (pLed1->bLedWPSBlinkInProgress) {
- pLed1->bLedWPSBlinkInProgress = false;
- _cancel_timer_ex(&(pLed1->BlinkTimer));
-
- pLed1->BlinkingLedState = RTW_LED_OFF;
- pLed1->CurrLedState = RTW_LED_OFF;
-
- if (pLed1->bLedOn)
- _set_timer(&(pLed->BlinkTimer), 0);
- }
-
- if (!pLed->bLedWPSBlinkInProgress) {
+ if (!pLed->bLedWPSBlinkInProgress) {
if (pLed->bLedNoLinkBlinkInProgress) {
_cancel_timer_ex(&(pLed->BlinkTimer));
pLed->bLedNoLinkBlinkInProgress = false;
}
+ if (pLed->bLedLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
if (pLed->bLedBlinkInProgress) {
_cancel_timer_ex(&(pLed->BlinkTimer));
pLed->bLedBlinkInProgress = false;
}
pLed->bLedWPSBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_WPS;
- if (pLed->bLedOn) {
+ if (pLed->bLedOn)
pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- } else {
+ else
pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- }
- }
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
break;
- case LED_CTL_STOP_WPS: /* WPS connect success */
- if (pLed->bLedWPSBlinkInProgress) {
+ case LED_CTL_STOP_WPS:
+ if (pLed->bLedNoLinkBlinkInProgress) {
_cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = false;
+ pLed->bLedNoLinkBlinkInProgress = false;
}
-
- pLed->bLedNoLinkBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
-
- break;
- case LED_CTL_STOP_WPS_FAIL: /* WPS authentication fail */
- if (pLed->bLedWPSBlinkInProgress) {
+ if (pLed->bLedLinkBlinkInProgress) {
_cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = false;
+ pLed->bLedLinkBlinkInProgress = false;
}
- pLed->bLedNoLinkBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress)
+ _cancel_timer_ex(&(pLed->BlinkTimer));
else
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS_STOP;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ } else {
pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
-
- /* LED1 settings */
- if (pLed1->bLedWPSBlinkInProgress)
- _cancel_timer_ex(&(pLed1->BlinkTimer));
- else
- pLed1->bLedWPSBlinkInProgress = true;
- pLed1->CurrLedState = LED_BLINK_WPS_STOP;
- if (pLed1->bLedOn)
- pLed1->BlinkingLedState = RTW_LED_OFF;
- else
- pLed1->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
break;
- case LED_CTL_STOP_WPS_FAIL_OVERLAP: /* WPS session overlap */
+ case LED_CTL_STOP_WPS_FAIL:
if (pLed->bLedWPSBlinkInProgress) {
_cancel_timer_ex(&(pLed->BlinkTimer));
pLed->bLedWPSBlinkInProgress = false;
else
pLed->BlinkingLedState = RTW_LED_ON;
_set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
-
- /* LED1 settings */
- if (pLed1->bLedWPSBlinkInProgress)
- _cancel_timer_ex(&(pLed1->BlinkTimer));
- else
- pLed1->bLedWPSBlinkInProgress = true;
- pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP;
- pLed1->BlinkTimes = 10;
- if (pLed1->bLedOn)
- pLed1->BlinkingLedState = RTW_LED_OFF;
- else
- pLed1->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
break;
case LED_CTL_POWER_OFF:
pLed->CurrLedState = RTW_LED_OFF;
pLed->BlinkingLedState = RTW_LED_OFF;
-
if (pLed->bLedNoLinkBlinkInProgress) {
_cancel_timer_ex(&(pLed->BlinkTimer));
pLed->bLedNoLinkBlinkInProgress = false;
_cancel_timer_ex(&(pLed->BlinkTimer));
pLed->bLedScanBlinkInProgress = false;
}
- if (pLed->bLedStartToLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedStartToLinkBlinkInProgress = false;
- }
- if (pLed1->bLedWPSBlinkInProgress) {
- _cancel_timer_ex(&(pLed1->BlinkTimer));
- pLed1->bLedWPSBlinkInProgress = false;
- }
- pLed1->BlinkingLedState = LED_UNKNOWN;
- SwLedOff(padapter, pLed);
- SwLedOff(padapter, pLed1);
- break;
- default:
- break;
- }
-
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Led %d\n", pLed->CurrLedState));
-}
-
-
-
- /* Sercomm-Belkin, added by chiyoko, 20090415 */
-static void
-SwLedControlMode5(
- struct adapter *padapter,
- enum LED_CTL_MODE LedAction
-)
-{
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct LED_871x *pLed = &(ledpriv->SwLed0);
-
- switch (LedAction) {
- case LED_CTL_POWER_ON:
- case LED_CTL_NO_LINK:
- case LED_CTL_LINK: /* solid blue */
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
-
- _set_timer(&(pLed->BlinkTimer), 0);
- break;
- case LED_CTL_SITE_SURVEY:
- if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) {
- } else if (!pLed->bLedScanBlinkInProgress) {
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
- pLed->bLedScanBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_SCAN;
- pLed->BlinkTimes = 24;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
- case LED_CTL_TX:
- case LED_CTL_RX:
- if (!pLed->bLedBlinkInProgress) {
- if (pLed->CurrLedState == LED_BLINK_SCAN)
- return;
- pLed->bLedBlinkInProgress = true;
- pLed->CurrLedState = LED_BLINK_TXRX;
- pLed->BlinkTimes = 2;
- if (pLed->bLedOn)
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- break;
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
-
- if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = false;
- }
SwLedOff(padapter, pLed);
break;
default:
RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Led %d\n", pLed->CurrLedState));
}
- /* WNC-Corega, added by chiyoko, 20090902 */
-static void
-SwLedControlMode6(
- struct adapter *padapter,
- enum LED_CTL_MODE LedAction
-)
-{
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct LED_871x *pLed0 = &(ledpriv->SwLed0);
-
- switch (LedAction) {
- case LED_CTL_POWER_ON:
- case LED_CTL_LINK:
- case LED_CTL_NO_LINK:
- _cancel_timer_ex(&(pLed0->BlinkTimer));
- pLed0->CurrLedState = RTW_LED_ON;
- pLed0->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed0->BlinkTimer), 0);
- break;
- case LED_CTL_POWER_OFF:
- SwLedOff(padapter, pLed0);
- break;
- default:
- break;
- }
-
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("ledcontrol 6 Led %d\n", pLed0->CurrLedState));
-}
-
/* */
/* Description: */
/* Handler function of LED Blinking. */
-/* We dispatch acture LED blink action according to LedStrategy. */
/* */
void BlinkHandler(struct LED_871x *pLed)
{
struct adapter *padapter = pLed->padapter;
- struct led_priv *ledpriv = &(padapter->ledpriv);
if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped))
return;
- switch (ledpriv->LedStrategy) {
- case SW_LED_MODE0:
- SwLedBlink(pLed);
- break;
- case SW_LED_MODE1:
- SwLedBlink1(pLed);
- break;
- case SW_LED_MODE2:
- SwLedBlink2(pLed);
- break;
- case SW_LED_MODE3:
- SwLedBlink3(pLed);
- break;
- case SW_LED_MODE4:
- SwLedBlink4(pLed);
- break;
- case SW_LED_MODE5:
- SwLedBlink5(pLed);
- break;
- case SW_LED_MODE6:
- SwLedBlink6(pLed);
- break;
- default:
- break;
- }
+ SwLedBlink1(pLed);
}
void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE LedAction)
LedAction == LED_CTL_POWER_ON))
return;
- switch (ledpriv->LedStrategy) {
- case SW_LED_MODE0:
- break;
- case SW_LED_MODE1:
- SwLedControlMode1(padapter, LedAction);
- break;
- case SW_LED_MODE2:
- SwLedControlMode2(padapter, LedAction);
- break;
- case SW_LED_MODE3:
- SwLedControlMode3(padapter, LedAction);
- break;
- case SW_LED_MODE4:
- SwLedControlMode4(padapter, LedAction);
- break;
- case SW_LED_MODE5:
- SwLedControlMode5(padapter, LedAction);
- break;
- case SW_LED_MODE6:
- SwLedControlMode6(padapter, LedAction);
- break;
- default:
- break;
- }
-
- RT_TRACE(_module_rtl8712_led_c_, _drv_info_,
- ("LedStrategy:%d, LedAction %d\n",
- ledpriv->LedStrategy, LedAction));
+ SwLedControlMode1(padapter, LedAction);
}
return _FAIL;
}
- if (*(p + 1)) {
+ if (len) {
if (len > NDIS_802_11_LENGTH_SSID) {
DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
return _FAIL;
}
- memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
- bssid->Ssid.SsidLength = *(p + 1);
+ memcpy(bssid->Ssid.Ssid, (p + 2), len);
+ bssid->Ssid.SsidLength = len;
} else {
bssid->Ssid.SsidLength = 0;
}
rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
- spin_lock_bh(&pmlmepriv->lock);
- rtw_sitesurvey_cmd(padapter, &ssid, 1, NULL, 0);
- spin_unlock_bh(&pmlmepriv->lock);
+ spin_lock_bh(&pmlmepriv->lock);
+ rtw_sitesurvey_cmd(padapter, &ssid, 1, NULL, 0);
+ spin_unlock_bh(&pmlmepriv->lock);
}
void p2p_concurrent_handler(struct adapter *padapter);
return cnt;
}
-int rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, struct __queue *queue)
-{
- spin_lock_bh(&queue->lock);
-
- rtw_list_delete(&precvbuf->list);
- rtw_list_insert_head(&precvbuf->list, get_list_head(queue));
-
- spin_unlock_bh(&queue->lock);
-
- return _SUCCESS;
-}
-
-int rtw_enqueue_recvbuf(struct recv_buf *precvbuf, struct __queue *queue)
-{
- unsigned long irqL;
- spin_lock_irqsave(&queue->lock, irqL);
-
- rtw_list_delete(&precvbuf->list);
-
- rtw_list_insert_tail(&precvbuf->list, get_list_head(queue));
- spin_unlock_irqrestore(&queue->lock, irqL);
- return _SUCCESS;
-}
-
-struct recv_buf *rtw_dequeue_recvbuf (struct __queue *queue)
-{
- unsigned long irqL;
- struct recv_buf *precvbuf;
- struct list_head *plist, *phead;
-
- spin_lock_irqsave(&queue->lock, irqL);
-
- if (_rtw_queue_empty(queue)) {
- precvbuf = NULL;
- } else {
- phead = get_list_head(queue);
-
- plist = phead->next;
-
- precvbuf = container_of(plist, struct recv_buf, list);
-
- rtw_list_delete(&precvbuf->list);
- }
-
- spin_unlock_irqrestore(&queue->lock, irqL);
-
- return precvbuf;
-}
-
static int recvframe_chkmic(struct adapter *adapter,
struct recv_frame *precvframe)
{
static struct recv_frame *portctrl(struct adapter *adapter,
struct recv_frame *precv_frame)
{
- u8 *psta_addr = NULL, *ptr;
+ 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 = 0;
+ u16 ether_type;
u16 eapol_type = 0x888e;/* for Funia BD's WPA issue */
struct rx_pkt_attrib *pattrib;
- __be16 be_tmp;
pstapriv = &adapter->stapriv;
- psta = rtw_get_stainfo(pstapriv, psta_addr);
auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
pfhdr = precv_frame;
pattrib = &pfhdr->attrib;
psta_addr = pattrib->ta;
+ psta = rtw_get_stainfo(pstapriv, psta_addr);
prtnframe = NULL;
RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm=%d\n", adapter->securitypriv.dot11AuthAlgrthm));
if (auth_alg == 2) {
+ /* get ether_type */
+ ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE;
+ memcpy(ðer_type, ptr, 2);
+ ether_type = ntohs((unsigned short)ether_type);
+
if ((psta != NULL) && (psta->ieee8021x_blocked)) {
/* blocked */
/* only accept EAPOL frame */
RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked==1\n"));
- prtnframe = precv_frame;
-
- /* get ether_type */
- ptr = ptr+pfhdr->attrib.hdrlen+pfhdr->attrib.iv_len+LLC_HEADER_SIZE;
- memcpy(&be_tmp, ptr, 2);
- ether_type = ntohs(be_tmp);
-
if (ether_type == eapol_type) {
prtnframe = precv_frame;
} else {
return true;
prhdr = container_of(plist, struct recv_frame, list);
- pattrib = &prhdr->attrib;
+ pattrib = &prhdr->attrib;
preorder_ctrl->indicate_seq = pattrib->seq_num;
}
/* Insert MIC into payload */
for (j = 0; j < 8; j++)
- pframe[payload_index+j] = mic[j]; /* message[payload_index+j] = mic[j]; */
+ pframe[payload_index+j] = mic[j];
payload_index = hdrlen + 8;
for (i = 0; i < num_blocks; i++) {
pIE = (struct ndis_802_11_var_ie *)rtw_get_ie(pvar_ie, _SUPPORTEDRATES_IE_, &ie_len, var_ie_len);
if (pIE == NULL)
return _FAIL;
+ if (ie_len > NDIS_802_11_LENGTH_RATES_EX)
+ return _FAIL;
memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates, pIE->data, ie_len);
supportRateNum = ie_len;
pIE = (struct ndis_802_11_var_ie *)rtw_get_ie(pvar_ie, _EXT_SUPPORTEDRATES_IE_, &ie_len, var_ie_len);
- if (pIE)
+ if (pIE) {
+ if (supportRateNum + ie_len > NDIS_802_11_LENGTH_RATES_EX)
+ return _FAIL;
memcpy((pmlmeinfo->FW_sta_info[cam_idx].SupportedRates + supportRateNum), pIE->data, ie_len);
+ }
return _SUCCESS;
}
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
return;
LedCfg = rtw_read8(padapter, REG_LEDCFG2);
- switch (pLed->LedPin) {
- case LED_PIN_LED0:
- rtw_write8(padapter, REG_LEDCFG2, (LedCfg&0xf0)|BIT5|BIT6); /* SW control led0 on. */
- break;
- case LED_PIN_LED1:
- rtw_write8(padapter, REG_LEDCFG2, (LedCfg&0x0f)|BIT5); /* SW control led1 on. */
- break;
- default:
- break;
- }
+ rtw_write8(padapter, REG_LEDCFG2, (LedCfg&0xf0)|BIT5|BIT6); /* SW control led0 on. */
pLed->bLedOn = true;
}
LedCfg = rtw_read8(padapter, REG_LEDCFG2);/* 0x4E */
- switch (pLed->LedPin) {
- case LED_PIN_LED0:
- if (pHalData->bLedOpenDrain) {
+ if (pHalData->bLedOpenDrain) {
/* Open-drain arrangement for controlling the LED) */
- LedCfg &= 0x90; /* Set to software control. */
- rtw_write8(padapter, REG_LEDCFG2, (LedCfg|BIT3));
- LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG);
- LedCfg &= 0xFE;
- rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
- } else {
- rtw_write8(padapter, REG_LEDCFG2, (LedCfg|BIT3|BIT5|BIT6));
- }
- break;
- case LED_PIN_LED1:
- LedCfg &= 0x0f; /* Set to software control. */
+ LedCfg &= 0x90; /* Set to software control. */
rtw_write8(padapter, REG_LEDCFG2, (LedCfg|BIT3));
- break;
- default:
- break;
+ LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG);
+ LedCfg &= 0xFE;
+ rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
+ } else {
+ rtw_write8(padapter, REG_LEDCFG2, (LedCfg|BIT3|BIT5|BIT6));
}
exit:
pLed->bLedOn = false;
void rtl8188eu_InitSwLeds(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;
- InitLed871x(padapter, &(pledpriv->SwLed0), LED_PIN_LED0);
-
- InitLed871x(padapter, &(pledpriv->SwLed1), LED_PIN_LED1);
+ InitLed871x(padapter, &(pledpriv->SwLed0));
}
/* Description: */
struct led_priv *ledpriv = &(padapter->ledpriv);
DeInitLed871x(&(ledpriv->SwLed0));
- DeInitLed871x(&(ledpriv->SwLed1));
}
#include <rtl8188e_hal.h>
-void rtl8188eu_init_recvbuf(struct adapter *padapter, struct recv_buf *precvbuf)
-{
- precvbuf->transfer_len = 0;
-
- precvbuf->len = 0;
-
- precvbuf->ref_cnt = 0;
-
- if (precvbuf->pbuf) {
- precvbuf->pdata = precvbuf->pbuf;
- precvbuf->phead = precvbuf->pbuf;
- precvbuf->ptail = precvbuf->pbuf;
- precvbuf->pend = precvbuf->pdata + MAX_RECVBUF_SZ;
- }
-}
-
int rtl8188eu_init_recv_priv(struct adapter *padapter)
{
struct recv_priv *precvpriv = &padapter->recvpriv;
precvbuf = (struct recv_buf *)precvpriv->precv_buf;
for (i = 0; i < NR_RECVBUFF; i++) {
- _rtw_init_listhead(&precvbuf->list);
- spin_lock_init(&precvbuf->recvbuf_lock);
- precvbuf->alloc_sz = MAX_RECVBUF_SZ;
res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf);
if (res == _FAIL)
break;
- precvbuf->ref_cnt = 0;
precvbuf->adapter = padapter;
precvbuf++;
}
{
}
-static void _InitHWLed(struct adapter *Adapter)
-{
- struct led_priv *pledpriv = &(Adapter->ledpriv);
-
- if (pledpriv->LedStrategy != HW_LED)
- return;
-
-/* HW led control */
-/* to do .... */
-/* must consider cases of antenna diversity/ commbo card/solo card/mini card */
-}
-
static void _InitRDGSetting(struct adapter *Adapter)
{
rtw_write8(Adapter, REG_RD_CTRL, 0xFF);
rtw_write16(Adapter, REG_PKT_VO_VI_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
rtw_write16(Adapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
- _InitHWLed(Adapter);
-
/* Keep RfRegChnlVal for later use. */
haldata->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, (enum rf_radio_path)0, RF_CHNLBW, bRFRegOffsetMask);
haldata->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, (enum rf_radio_path)1, RF_CHNLBW, bRFRegOffsetMask);
/* EEPROM/EFUSE Content Parsing */
/* */
/* */
-static void _ReadLEDSetting(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail)
-{
- struct led_priv *pledpriv = &(Adapter->ledpriv);
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
-
- pledpriv->bRegUseLed = true;
- pledpriv->LedStrategy = SW_LED_MODE1;
- haldata->bLedOpenDrain = true;/* Support Open-drain arrangement for controlling the LED. */
-}
-
static void Hal_EfuseParsePIDVID_8188EU(struct adapter *adapt, u8 *hwinfo, bool AutoLoadFail)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
/* */
Hal_InitChannelPlan(adapt);
Hal_CustomizeByCustomerID_8188EU(adapt);
-
- _ReadLEDSetting(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
}
static void _ReadPROMContent(
} else {
rtw_reset_continual_urb_error(adapter_to_dvobj(adapt));
- precvbuf->transfer_len = purb->actual_length;
skb_put(precvbuf->pskb, purb->actual_length);
skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb);
precvbuf->reuse = true;
}
- rtl8188eu_init_recvbuf(adapter, precvbuf);
-
/* re-assign for linux based on skb */
if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) {
precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
tmpaddr = (size_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;
}
pipe = ffaddr2pipehdl(pdvobj, addr);
usb_fill_bulk_urb(purb, pusbd, pipe,
- precvbuf->pbuf,
+ precvbuf->pskb->data,
MAX_RECVBUF_SZ,
usb_read_port_complete,
precvbuf);/* context is precvbuf */
#include <osdep_service.h>
#include <wlan_bssdef.h>
-#include <drv_types_linux.h>
#include <rtw_ht.h>
#include <rtw_cmd.h>
#include <rtw_xmit.h>
+++ /dev/null
-/******************************************************************************
- *
- * 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.
- *
- * 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, USA
- *
- *
- ******************************************************************************/
-#ifndef __DRV_TYPES_LINUX_H__
-#define __DRV_TYPES_LINUX_H__
-
-
-#endif
};
#define INTERRUPT_MSG_FORMAT_LEN 60
-void rtl8188eu_init_recvbuf(struct adapter *padapter, struct recv_buf *buf);
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);
u8 rtw_set_ch_cmd(struct adapter *padapter, u8 ch, u8 bw, u8 ch_offset,
u8 enqueue);
u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue);
-u8 rtw_led_blink_cmd(struct adapter *padapter, struct LED_871x *pLed);
u8 rtw_set_csa_cmd(struct adapter *padapter, u8 new_ch_no);
u8 rtw_tdls_cmd(struct adapter *padapter, u8 *addr, u8 option);
#include <osdep_service.h>
#include <drv_types.h>
-#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000)
-
-#define LED_BLINK_NORMAL_INTERVAL 100
-#define LED_BLINK_SLOWLY_INTERVAL 200
-#define LED_BLINK_LONG_INTERVAL 400
-
#define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000
#define LED_BLINK_LINK_INTERVAL_ALPHA 500 /* 500 */
#define LED_BLINK_SCAN_INTERVAL_ALPHA 180 /* 150 */
#define LED_BLINK_FASTER_INTERVAL_ALPHA 50
#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000
-#define LED_BLINK_NORMAL_INTERVAL_NETTRONIX 100
-#define LED_BLINK_SLOWLY_INTERVAL_NETTRONIX 2000
-
-#define LED_BLINK_SLOWLY_INTERVAL_PORNET 1000
-#define LED_BLINK_NORMAL_INTERVAL_PORNET 100
-
-#define LED_BLINK_FAST_INTERVAL_BITLAND 30
-
-/* 060403, rcnjko: Customized for AzWave. */
-#define LED_CM2_BLINK_ON_INTERVAL 250
-#define LED_CM2_BLINK_OFF_INTERVAL 4750
-
-#define LED_CM8_BLINK_INTERVAL 500 /* for QMI */
-#define LED_CM8_BLINK_OFF_INTERVAL 3750 /* for QMI */
-
-/* 080124, lanhsin: Customized for RunTop */
-#define LED_RunTop_BLINK_INTERVAL 300
-
-/* 060421, rcnjko: Customized for Sercomm Printer Server case. */
-#define LED_CM3_BLINK_INTERVAL 1500
-
enum LED_CTL_MODE {
- LED_CTL_POWER_ON = 1,
- LED_CTL_LINK = 2,
- LED_CTL_NO_LINK = 3,
- LED_CTL_TX = 4,
- LED_CTL_RX = 5,
- LED_CTL_SITE_SURVEY = 6,
- LED_CTL_POWER_OFF = 7,
- LED_CTL_START_TO_LINK = 8,
- LED_CTL_START_WPS = 9,
- LED_CTL_STOP_WPS = 10,
- LED_CTL_START_WPS_BOTTON = 11, /* added for runtop */
- LED_CTL_STOP_WPS_FAIL = 12, /* added for ALPHA */
- LED_CTL_STOP_WPS_FAIL_OVERLAP = 13, /* added for BELKIN */
- LED_CTL_CONNECTION_NO_TRANSFER = 14,
+ LED_CTL_POWER_ON,
+ LED_CTL_LINK,
+ LED_CTL_NO_LINK,
+ LED_CTL_TX,
+ LED_CTL_RX ,
+ LED_CTL_SITE_SURVEY,
+ LED_CTL_POWER_OFF,
+ LED_CTL_START_TO_LINK,
+ LED_CTL_START_WPS,
+ LED_CTL_STOP_WPS,
+ LED_CTL_START_WPS_BOTTON,
+ LED_CTL_STOP_WPS_FAIL
};
enum LED_STATE_871x {
- LED_UNKNOWN = 0,
- RTW_LED_ON = 1,
- RTW_LED_OFF = 2,
- LED_BLINK_NORMAL = 3,
- LED_BLINK_SLOWLY = 4,
- LED_BLINK_POWER_ON = 5,
- LED_BLINK_SCAN = 6, /* LED is blinking during scanning period,
- * the # of times to blink is depend on time
- * for scanning. */
- LED_BLINK_NO_LINK = 7, /* LED is blinking during no link state. */
- LED_BLINK_StartToBlink = 8,/* Customzied for Sercomm Printer
- * Server case */
- LED_BLINK_TXRX = 9,
- LED_BLINK_WPS = 10, /* LED is blinkg during WPS communication */
- LED_BLINK_WPS_STOP = 11, /* for ALPHA */
- LED_BLINK_WPS_STOP_OVERLAP = 12, /* for BELKIN */
- LED_BLINK_RUNTOP = 13, /* Customized for RunTop */
- LED_BLINK_CAMEO = 14,
- LED_BLINK_XAVI = 15,
- LED_BLINK_ALWAYS_ON = 16,
-};
-
-enum LED_PIN_871x {
- LED_PIN_NULL = 0,
- LED_PIN_LED0 = 1,
- LED_PIN_LED1 = 2,
- LED_PIN_LED2 = 3,
- LED_PIN_GPIO0 = 4,
+ LED_UNKNOWN,
+ RTW_LED_ON,
+ RTW_LED_OFF,
+ LED_BLINK_NORMAL,
+ LED_BLINK_SLOWLY,
+ LED_BLINK_POWER_ON,
+ LED_BLINK_SCAN,
+ LED_BLINK_TXRX,
+ LED_BLINK_WPS,
+ LED_BLINK_WPS_STOP
};
struct LED_871x {
struct adapter *padapter;
- enum LED_PIN_871x LedPin; /* Identify how to implement this
- * SW led. */
enum LED_STATE_871x CurrLedState; /* Current LED state. */
enum LED_STATE_871x BlinkingLedState; /* Next state for blinking,
* either RTW_LED_ON or RTW_LED_OFF are. */
((struct LED_871x *)_LED_871x)->CurrLedState == LED_BLINK_WPS_STOP || \
((struct LED_871x *)_LED_871x)->bLedWPSBlinkInProgress)
-#define IS_LED_BLINKING(_LED_871x) \
- (((struct LED_871x *)_LED_871x)->bLedWPSBlinkInProgress || \
- ((struct LED_871x *)_LED_871x)->bLedScanBlinkInProgress)
-
-/* LED customization. */
-
-enum LED_STRATEGY_871x {
- SW_LED_MODE0 = 0, /* SW control 1 LED via GPIO0. It is default option.*/
- SW_LED_MODE1 = 1, /* 2 LEDs, through LED0 and LED1. For ALPHA. */
- SW_LED_MODE2 = 2, /* SW control 1 LED via GPIO0, customized for AzWave
- * 8187 minicard. */
- SW_LED_MODE3 = 3, /* SW control 1 LED via GPIO0, customized for Sercomm
- * Printer Server case. */
- SW_LED_MODE4 = 4, /* for Edimax / Belkin */
- SW_LED_MODE5 = 5, /* for Sercomm / Belkin */
- SW_LED_MODE6 = 6, /* for 88CU minicard, porting from ce SW_LED_MODE7 */
- HW_LED = 50, /* HW control 2 LEDs, LED0 and LED1 (there are 4
- * different control modes, see MAC.CONFIG1 for details.)*/
- LED_ST_NONE = 99,
-};
-
void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE LedAction);
struct led_priv{
/* add for led control */
struct LED_871x SwLed0;
- struct LED_871x SwLed1;
- enum LED_STRATEGY_871x LedStrategy;
u8 bRegUseLed;
void (*LedControlHandler)(struct adapter *padapter,
enum LED_CTL_MODE LedAction);
void ResetLedStatus(struct LED_871x *pLed);
-void InitLed871x(struct adapter *padapter, struct LED_871x *pLed,
- enum LED_PIN_871x LedPin);
+void InitLed871x(struct adapter *padapter, struct LED_871x *pLed);
void DeInitLed871x(struct LED_871x *pLed);
};
struct recv_buf {
- struct list_head list;
- spinlock_t recvbuf_lock;
- u32 ref_cnt;
struct adapter *adapter;
- u8 *pbuf;
- u8 *pallocated_buf;
- u32 len;
- u8 *phead;
- u8 *pdata;
- u8 *ptail;
- u8 *pend;
struct urb *purb;
- dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */
- u32 alloc_sz;
- u8 irp_pending;
- int transfer_len;
struct sk_buff *pskb;
u8 reuse;
};
void rtw_free_recvframe_queue(struct __queue *pframequeue,
struct __queue *pfree_recv_queue);
u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter);
-int rtw_enqueue_recvbuf_to_head(struct recv_buf *buf, struct __queue *queue);
-int rtw_enqueue_recvbuf(struct recv_buf *precvbuf, struct __queue *queue);
-struct recv_buf *rtw_dequeue_recvbuf(struct __queue *queue);
void rtw_reordering_ctrl_timeout_handler(void *pcontext);
size_t buf_len;
};
-extern int rtw_ht_enable;
-extern int rtw_cbw40_enable;
-extern int rtw_ampdu_enable;/* for enable tx_ampdu */
-
#define NR_XMITFRAME 256
struct xmit_priv;
if (wpa_len > 0) {
p = buf;
_rtw_memset(buf, 0, MAX_WPA_IE_LEN);
- p += sprintf(p, "wpa_ie =");
+ p += sprintf(p, "wpa_ie=");
for (i = 0; i < wpa_len; i++)
p += sprintf(p, "%02x", wpa_ie[i]);
if (rsn_len > 0) {
p = buf;
_rtw_memset(buf, 0, MAX_WPA_IE_LEN);
- p += sprintf(p, "rsn_ie =");
+ p += sprintf(p, "rsn_ie=");
for (i = 0; i < rsn_len; i++)
p += sprintf(p, "%02x", rsn_ie[i]);
_rtw_memset(&iwe, 0, sizeof(iwe));
/* Commented by Albert 2010/10/12 */
/* Because of the output size limitation, I had removed the "Role" information. */
/* About the "Role" information, we will use the new private IOCTL to get the "Role" information. */
- sprintf(extra, "\n\nStatus =%.2d\n", rtw_p2p_state(pwdinfo));
+ sprintf(extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo));
wrqu->data.length = strlen(extra);
return ret;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- sprintf(extra, "\n\nCM =%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
+ sprintf(extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
wrqu->data.length = strlen(extra);
return ret;
}
pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
- sprintf(extra, "\n\nRole =%.2d\n", rtw_p2p_role(pwdinfo));
+ sprintf(extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo));
wrqu->data.length = strlen(extra);
return ret;
}
DBG_88E("[%s] Op_ch = %02x\n", __func__, pwdinfo->operating_channel);
- sprintf(extra, "\n\nOp_ch =%.2d\n", pwdinfo->operating_channel);
+ sprintf(extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel);
wrqu->data.length = strlen(extra);
return ret;
}
u8 blnMatch = 0;
u16 attr_content = 0;
uint attr_contentlen = 0;
- /* 6 is the string "wpsCM =", 17 is the MAC addr, we have to clear it at wrqu->data.pointer */
+ /* 6 is the string "wpsCM=", 17 is the MAC addr, we have to clear it at wrqu->data.pointer */
u8 attr_content_str[6 + 17] = {0x00};
/* Commented by Albert 20110727 */
rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *) &be_tmp, &attr_contentlen);
if (attr_contentlen) {
attr_content = be16_to_cpu(be_tmp);
- sprintf(attr_content_str, "\n\nM =%.4d", attr_content);
+ sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
blnMatch = 1;
}
}
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
if (!blnMatch)
- sprintf(attr_content_str, "\n\nM = 0000");
+ sprintf(attr_content_str, "\n\nM=0000");
if (copy_to_user(wrqu->data.pointer, attr_content_str, 6 + 17))
return -EFAULT;
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
if (!blnMatch)
- snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add = NULL");
+ snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add=NULL");
else
- snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add =%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
+ snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
if (copy_to_user(wrqu->data.pointer, go_devadd_str, sizeof(go_devadd_str)))
u8 blnMatch = 0;
u8 dev_type[8] = {0x00};
uint dev_type_len = 0;
- u8 dev_type_str[17 + 9] = {0x00}; /* +9 is for the str "dev_type =", we have to clear it at wrqu->data.pointer */
+ u8 dev_type_str[17 + 9] = {0x00}; /* +9 is for the str "dev_type=", we have to clear it at wrqu->data.pointer */
/* Commented by Albert 20121209 */
/* The input data is the MAC address which the application wants to know its device type. */
memcpy(&be_tmp, dev_type, 2);
type = be16_to_cpu(be_tmp);
- sprintf(dev_type_str, "\n\nN =%.2d", type);
+ sprintf(dev_type_str, "\n\nN=%.2d", type);
blnMatch = 1;
}
}
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
if (!blnMatch)
- sprintf(dev_type_str, "\n\nN = 00");
+ sprintf(dev_type_str, "\n\nN=00");
if (copy_to_user(wrqu->data.pointer, dev_type_str, 9 + 17)) {
return -EFAULT;
u8 blnMatch = 0;
u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = {0x00};
uint dev_len = 0;
- u8 dev_name_str[WPS_MAX_DEVICE_NAME_LEN + 5] = {0x00}; /* +5 is for the str "devN =", we have to clear it at wrqu->data.pointer */
+ u8 dev_name_str[WPS_MAX_DEVICE_NAME_LEN + 5] = {0x00}; /* +5 is for the str "devN=", we have to clear it at wrqu->data.pointer */
/* Commented by Albert 20121225 */
/* The input data is the MAC address which the application wants to know its device name. */
if (wpsie) {
rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
if (dev_len) {
- sprintf(dev_name_str, "\n\nN =%s", dev_name);
+ sprintf(dev_name_str, "\n\nN=%s", dev_name);
blnMatch = 1;
}
}
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
if (!blnMatch)
- sprintf(dev_name_str, "\n\nN = 0000");
+ sprintf(dev_name_str, "\n\nN=0000");
if (copy_to_user(wrqu->data.pointer, dev_name_str, 5 + ((dev_len > 17) ? dev_len : 17)))
return -EFAULT;
u8 attr_content[2] = {0x00};
u8 inv_proc_str[17 + 8] = {0x00};
- /* +8 is for the str "InvProc =", we have to clear it at wrqu->data.pointer */
+ /* +8 is for the str "InvProc=", we have to clear it at wrqu->data.pointer */
/* Commented by Ouden 20121226 */
/* The application wants to know P2P initiation procedure is supported or not. */
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
if (!blnMatch) {
- sprintf(inv_proc_str, "\nIP =-1");
+ sprintf(inv_proc_str, "\nIP=-1");
} else {
if (attr_content[0] & 0x20)
- sprintf(inv_proc_str, "\nIP = 1");
+ sprintf(inv_proc_str, "\nIP=1");
else
- sprintf(inv_proc_str, "\nIP = 0");
+ sprintf(inv_proc_str, "\nIP=0");
}
if (copy_to_user(wrqu->data.pointer, inv_proc_str, 8 + 17))
return -EFAULT;
/* The input data contains two informations. */
/* 1. First information is the P2P device address which you want to send to. */
/* 2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */
- /* Command line sample: iwpriv wlan0 p2p_set invite ="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */
+ /* Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */
/* Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */
DBG_88E("[%s] data = %s\n", __func__, extra);
#ifdef CONFIG_88EU_P2P
DBG_88E("[%s] extra = %s\n", __func__, extra);
- if (!memcmp(extra, "enable =", 7)) {
+ if (!memcmp(extra, "enable=", 7)) {
rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]);
- } else if (!memcmp(extra, "setDN =", 6)) {
+ } else if (!memcmp(extra, "setDN=", 6)) {
wrqu->data.length -= 6;
rtw_p2p_setDN(dev, info, wrqu, &extra[6]);
- } else if (!memcmp(extra, "profilefound =", 13)) {
+ } else if (!memcmp(extra, "profilefound=", 13)) {
wrqu->data.length -= 13;
rtw_p2p_profilefound(dev, info, wrqu, &extra[13]);
- } else if (!memcmp(extra, "prov_disc =", 10)) {
+ } else if (!memcmp(extra, "prov_disc=", 10)) {
wrqu->data.length -= 10;
rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]);
- } else if (!memcmp(extra, "nego =", 5)) {
+ } else if (!memcmp(extra, "nego=", 5)) {
wrqu->data.length -= 5;
rtw_p2p_connect(dev, info, wrqu, &extra[5]);
- } else if (!memcmp(extra, "intent =", 7)) {
+ } else if (!memcmp(extra, "intent=", 7)) {
/* Commented by Albert 2011/03/23 */
/* The wrqu->data.length will include the null character */
/* So, we will decrease 7 + 1 */
wrqu->data.length -= 8;
rtw_p2p_set_intent(dev, info, wrqu, &extra[7]);
- } else if (!memcmp(extra, "ssid =", 5)) {
+ } else if (!memcmp(extra, "ssid=", 5)) {
wrqu->data.length -= 5;
rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]);
- } else if (!memcmp(extra, "got_wpsinfo =", 12)) {
+ } else if (!memcmp(extra, "got_wpsinfo=", 12)) {
wrqu->data.length -= 12;
rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]);
- } else if (!memcmp(extra, "listen_ch =", 10)) {
+ } else if (!memcmp(extra, "listen_ch=", 10)) {
/* Commented by Albert 2011/05/24 */
/* The wrqu->data.length will include the null character */
/* So, we will decrease (10 + 1) */
wrqu->data.length -= 11;
rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]);
- } else if (!memcmp(extra, "op_ch =", 6)) {
+ } else if (!memcmp(extra, "op_ch=", 6)) {
/* Commented by Albert 2011/05/24 */
/* The wrqu->data.length will include the null character */
/* So, we will decrease (6 + 1) */
wrqu->data.length -= 7;
rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]);
- } else if (!memcmp(extra, "invite =", 7)) {
+ } else if (!memcmp(extra, "invite=", 7)) {
wrqu->data.length -= 8;
rtw_p2p_invite_req(dev, info, wrqu, &extra[7]);
- } else if (!memcmp(extra, "persistent =", 11)) {
+ } else if (!memcmp(extra, "persistent=", 11)) {
wrqu->data.length -= 11;
rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]);
}
"group_id", 8)) {
rtw_p2p_get_groupid(dev, info, wrqu, extra);
} else if (!memcmp((__force const char *)wrqu->data.pointer,
- "peer_deva_inv", 9)) {
+ "peer_deva_inv", 13)) {
/* Get the P2P device address when receiving the P2P Invitation request frame. */
rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra);
} else if (!memcmp((__force const char *)wrqu->data.pointer,
DBG_88E("%s: in =%s\n", __func__, extra);
- countPkTx = strncmp(extra, "count =", 5); /* strncmp true is 0 */
+ countPkTx = strncmp(extra, "count=", 6); /* strncmp true is 0 */
cotuTx = strncmp(extra, "background", 20);
CarrSprTx = strncmp(extra, "background, cs", 20);
scTx = strncmp(extra, "background, sc", 20);
DBG_88E("%s: %s\n", __func__, input);
bStartRx = (strncmp(input, "start", 5) == 0) ? 1 : 0; /* strncmp true is 0 */
- bStopRx = (strncmp(input, "stop", 5) == 0) ? 1 : 0; /* strncmp true is 0 */
+ bStopRx = (strncmp(input, "stop", 4) == 0) ? 1 : 0; /* strncmp true is 0 */
bQueryPhy = (strncmp(input, "phy", 3) == 0) ? 1 : 0; /* strncmp true is 0 */
if (bStartRx) {
static int rtw_uapsd_acvi_en;
static int rtw_uapsd_acvo_en;
-int rtw_ht_enable = 1;
-int rtw_cbw40_enable = 3; /* 0 :disable, bit(0): enable 2.4g, bit(1): enable 5g */
-int rtw_ampdu_enable = 1;/* for enable tx_ampdu */
+static int rtw_ht_enable = 1;
+static int rtw_cbw40_enable = 3; /* 0 :disable, bit(0): enable 2.4g, bit(1): enable 5g */
+static int rtw_ampdu_enable = 1;/* for enable tx_ampdu */
static int rtw_rx_stbc = 1;/* 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_ampdu_amsdu;/* 0: disabled, 1:enabled, 2:auto */
{
int res = _SUCCESS;
- precvbuf->irp_pending = false;
precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL);
if (precvbuf->purb == NULL)
res = _FAIL;
precvbuf->pskb = NULL;
precvbuf->reuse = false;
- precvbuf->pallocated_buf = NULL;
- precvbuf->pbuf = NULL;
- precvbuf->pdata = NULL;
- precvbuf->phead = NULL;
- precvbuf->ptail = NULL;
- precvbuf->pend = NULL;
- precvbuf->transfer_len = 0;
- precvbuf->len = 0;
return res;
}
{
struct recv_priv *precvpriv = &padapter->recvpriv;
- precvbuf->ref_cnt--;
/* free skb in recv_buf */
dev_kfree_skb_any(precvbuf->pskb);
precvbuf->pskb = NULL;
precvbuf->reuse = false;
- if (!precvbuf->irp_pending)
- rtw_read_port(padapter, precvpriv->ff_hwaddr, 0,
- (unsigned char *)precvbuf);
+ rtw_read_port(padapter, precvpriv->ff_hwaddr, 0,
+ (unsigned char *)precvbuf);
}
static void _rtw_reordering_ctrl_timeout_handler(void *func_context)
MODULE_DEVICE_TABLE(usb, rtw_usb_id_tbl);
-static struct specific_device_id specific_device_id_tbl[] = {
- {} /* empty table for now */
-};
-
struct rtw_usb_drv {
struct usb_driver usbdrv;
int drv_registered;
static struct rtw_usb_drv *usb_drv = &rtl8188e_usb_drv;
-static inline int RT_usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
-{
- return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN;
-}
-
-static inline int RT_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd)
-{
- return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT;
-}
-
-static inline int RT_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
-{
- return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT;
-}
-
-static inline int RT_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd)
-{
- return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK;
-}
-
-static inline int RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd)
-{
- return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_in(epd);
-}
-
-static inline int RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd)
-{
- return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_out(epd);
-}
-
-static inline int usb_endpoint_is_int(const struct usb_endpoint_descriptor *epd)
-{
- return RT_usb_endpoint_xfer_int(epd) && RT_usb_endpoint_dir_in(epd);
-}
-
-static inline int RT_usb_endpoint_num(const struct usb_endpoint_descriptor *epd)
-{
- return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
-}
-
static u8 rtw_init_intf_priv(struct dvobj_priv *dvobj)
{
u8 rst = _SUCCESS;
pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
for (i = 0; i < pdvobjpriv->nr_endpoint; i++) {
+ int ep_num;
phost_endp = phost_iface->endpoint + i;
+
if (phost_endp) {
pendp_desc = &phost_endp->desc;
+ ep_num = usb_endpoint_num(pendp_desc);
- DBG_88E("\nusb_endpoint_descriptor(%d):\n", i);
- DBG_88E("bLength=%x\n", pendp_desc->bLength);
- DBG_88E("bDescriptorType=%x\n",
- pendp_desc->bDescriptorType);
- DBG_88E("bEndpointAddress=%x\n",
- pendp_desc->bEndpointAddress);
- DBG_88E("wMaxPacketSize=%d\n",
- le16_to_cpu(pendp_desc->wMaxPacketSize));
- DBG_88E("bInterval=%x\n", pendp_desc->bInterval);
-
- if (RT_usb_endpoint_is_bulk_in(pendp_desc)) {
- DBG_88E("RT_usb_endpoint_is_bulk_in = %x\n",
- RT_usb_endpoint_num(pendp_desc));
- pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = RT_usb_endpoint_num(pendp_desc);
+ if (usb_endpoint_is_bulk_in(pendp_desc)) {
+ pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = ep_num;
pdvobjpriv->RtNumInPipes++;
- } else if (usb_endpoint_is_int(pendp_desc)) {
- DBG_88E("usb_endpoint_is_int = %x, Interval = %x\n",
- RT_usb_endpoint_num(pendp_desc),
- pendp_desc->bInterval);
- pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = RT_usb_endpoint_num(pendp_desc);
+ } else if (usb_endpoint_is_int_in(pendp_desc)) {
+ pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] = ep_num;
pdvobjpriv->RtNumInPipes++;
- } else if (RT_usb_endpoint_is_bulk_out(pendp_desc)) {
- DBG_88E("RT_usb_endpoint_is_bulk_out = %x\n",
- RT_usb_endpoint_num(pendp_desc));
- pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] = RT_usb_endpoint_num(pendp_desc);
+ } else if (usb_endpoint_is_bulk_out(pendp_desc)) {
+ pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] = ep_num;
pdvobjpriv->RtNumOutPipes++;
}
- pdvobjpriv->ep_num[i] = RT_usb_endpoint_num(pendp_desc);
+ pdvobjpriv->ep_num[i] = ep_num;
}
}
- DBG_88E("nr_endpoint=%d, in_num=%d, out_num=%d\n\n",
- pdvobjpriv->nr_endpoint, pdvobjpriv->RtNumInPipes,
- pdvobjpriv->RtNumOutPipes);
-
- if (pusbd->speed == USB_SPEED_HIGH) {
+ if (pusbd->speed == USB_SPEED_HIGH)
pdvobjpriv->ishighspeed = true;
- DBG_88E("USB_SPEED_HIGH\n");
- } else {
+ else
pdvobjpriv->ishighspeed = false;
- DBG_88E("NON USB_SPEED_HIGH\n");
- }
- if (rtw_init_intf_priv(pdvobjpriv) == _FAIL) {
- RT_TRACE(_module_os_intfs_c_, _drv_err_,
- ("\n Can't INIT rtw_init_intf_priv\n"));
+ if (rtw_init_intf_priv(pdvobjpriv) == _FAIL)
goto free_dvobj;
- }
- /* 3 misc */
sema_init(&(pdvobjpriv->usb_suspend_sema), 0);
rtw_reset_continual_urb_error(pdvobjpriv);
RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n"));
}
-static void process_spec_devid(const struct usb_device_id *pdid)
-{
- u16 vid, pid;
- u32 flags;
- int i;
- int num = sizeof(specific_device_id_tbl) /
- sizeof(struct specific_device_id);
-
- for (i = 0; i < num; i++) {
- vid = specific_device_id_tbl[i].idVendor;
- pid = specific_device_id_tbl[i].idProduct;
- flags = specific_device_id_tbl[i].flags;
-
- if ((pdid->idVendor == vid) && (pdid->idProduct == pid) &&
- (flags&SPEC_DEV_ID_DISABLE_HT)) {
- rtw_ht_enable = 0;
- rtw_cbw40_enable = 0;
- rtw_ampdu_enable = 0;
- }
- }
-}
-
int rtw_hw_suspend(struct adapter *padapter)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_init\n"));
- /* step 0. */
- process_spec_devid(pdid);
-
/* Initialize dvobj_priv */
dvobj = usb_dvobj_init(pusb_intf);
if (dvobj == NULL) {
select WIRELESS_EXT
select WEXT_PRIV
select CRYPTO
+ select FW_LOADER
---help---
default:
RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():"
- "unknow CMD Element\n");
+ "unknown CMD Element\n");
return 1;
}
struct r8192_priv *priv = rtllib_priv(dev);
bool rt_status = true;
- u8 *firmware_img_buf[3] = { &Rtl8192PciEFwBootArray[0],
- &Rtl8192PciEFwMainArray[0],
- &Rtl8192PciEFwDataArray[0]};
-
- u32 firmware_img_len[3] = { sizeof(Rtl8192PciEFwBootArray),
- sizeof(Rtl8192PciEFwMainArray),
- sizeof(Rtl8192PciEFwDataArray)};
u32 file_length = 0;
u8 *mapped_file = NULL;
u8 init_step = 0;
" firmware state\n");
}
- priv->firmware_source = FW_SOURCE_IMG_FILE;
for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA;
init_step++) {
if (rst_opt == OPT_SYSTEM_RESET) {
- switch (priv->firmware_source) {
- case FW_SOURCE_IMG_FILE:
- {
- if (pfirmware->firmware_buf_size[init_step] == 0) {
- const char *fw_name[3] = {
- RTL8192E_BOOT_IMG_FW,
- RTL8192E_MAIN_IMG_FW,
- RTL8192E_DATA_IMG_FW
- };
- const struct firmware *fw_entry;
- int rc;
- rc = request_firmware(&fw_entry,
- fw_name[init_step], &priv->pdev->dev);
- if (rc < 0) {
- RT_TRACE(COMP_FIRMWARE, "request firm"
- "ware fail!\n");
- goto download_firmware_fail;
- }
- if (fw_entry->size >
+ if (pfirmware->firmware_buf_size[init_step] == 0) {
+ const char *fw_name[3] = {
+ RTL8192E_BOOT_IMG_FW,
+ RTL8192E_MAIN_IMG_FW,
+ RTL8192E_DATA_IMG_FW
+ };
+ const struct firmware *fw_entry;
+ int rc;
+ rc = request_firmware(&fw_entry,
+ fw_name[init_step],
+ &priv->pdev->dev);
+ if (rc < 0) {
+ RT_TRACE(COMP_FIRMWARE, "request firmware fail!\n");
+ goto download_firmware_fail;
+ }
+ if (fw_entry->size >
sizeof(pfirmware->firmware_buf[init_step])) {
- RT_TRACE(COMP_FIRMWARE, "img file size "
+ RT_TRACE(COMP_FIRMWARE, "img file size "
"exceed the container struct "
"buffer fail!\n");
- goto download_firmware_fail;
- }
+ goto download_firmware_fail;
+ }
- if (init_step != FW_INIT_STEP1_MAIN) {
- memcpy(pfirmware->firmware_buf[init_step],
+ if (init_step != FW_INIT_STEP1_MAIN) {
+ memcpy(pfirmware->firmware_buf[init_step],
fw_entry->data, fw_entry->size);
- pfirmware->firmware_buf_size[init_step] =
- fw_entry->size;
+ pfirmware->firmware_buf_size[init_step] =
+ fw_entry->size;
- } else {
- memset(pfirmware->firmware_buf[init_step],
+ } else {
+ memset(pfirmware->firmware_buf[init_step],
0, 128);
- memcpy(&pfirmware->firmware_buf[init_step][128],
+ memcpy(&pfirmware->firmware_buf[init_step][128],
fw_entry->data, fw_entry->size);
- pfirmware->firmware_buf_size[init_step] =
- fw_entry->size + 128;
- }
-
- if (rst_opt == OPT_SYSTEM_RESET)
- release_firmware(fw_entry);
+ pfirmware->firmware_buf_size[init_step] =
+ fw_entry->size + 128;
}
- mapped_file = pfirmware->firmware_buf[init_step];
- file_length = pfirmware->firmware_buf_size[init_step];
- break;
- }
- case FW_SOURCE_HEADER_FILE:
- mapped_file = firmware_img_buf[init_step];
- file_length = firmware_img_len[init_step];
- if (init_step == FW_INIT_STEP2_DATA) {
- memcpy(pfirmware->firmware_buf[init_step], mapped_file, file_length);
- pfirmware->firmware_buf_size[init_step] = file_length;
- }
- break;
- default:
- break;
+ if (rst_opt == OPT_SYSTEM_RESET)
+ release_firmware(fw_entry);
}
-
-
- } else if (rst_opt == OPT_FIRMWARE_RESET) {
- mapped_file = pfirmware->firmware_buf[init_step];
- file_length = pfirmware->firmware_buf_size[init_step];
}
+ mapped_file = pfirmware->firmware_buf[init_step];
+ file_length = pfirmware->firmware_buf_size[init_step];
+
rt_status = fw_download_code(dev, mapped_file, file_length);
if (!rt_status) {
goto download_firmware_fail;
DESC_PACKET_TYPE_NORMAL = 1,
};
-enum firmware_source {
- FW_SOURCE_IMG_FILE = 0,
- FW_SOURCE_HEADER_FILE = 1,
-};
-
enum firmware_status {
FW_STATUS_0_INIT = 0,
FW_STATUS_1_MOVE_BOOT_CODE = 1,
#include "r8192E_hwimg.h"
-u8 Rtl8192PciEFwBootArray[BootArrayLengthPciE] = {
-0x10,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x3c,0x08,0xbf,0xc0,0x25,0x08,0x00,0x08,
-0x3c,0x09,0xb0,0x03,0xad,0x28,0x00,0x20,0x40,0x80,0x68,0x00,0x00,0x00,0x00,0x00,
-0x3c,0x0a,0xd0,0x00,0x40,0x8a,0x60,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01,
-0x25,0x08,0xa8,0x04,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff,
-0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01,0x01,0x2a,0x10,0x2b,
-0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x00,0x00,0x25,0x4a,0x00,0x00,
-0x4c,0x8a,0x00,0x00,0x4c,0x89,0x08,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01,
-0x25,0x08,0xa8,0x04,0x3c,0x01,0x80,0x00,0x01,0x21,0x48,0x25,0x3c,0x0a,0xbf,0xc0,
-0x25,0x4a,0x00,0x7c,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0xad,0x00,0x00,0x00,
-0x21,0x08,0x00,0x04,0x01,0x09,0x10,0x2b,0x14,0x40,0xff,0xf8,0x00,0x00,0x00,0x00,
-0x3c,0x08,0x80,0x01,0x25,0x08,0x7f,0xff,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff,
-0x34,0x21,0xff,0xff,0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01,
-0x01,0x2a,0x10,0x2b,0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x01,
-0x25,0x4a,0x00,0x00,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff,0x01,0x41,0x50,0x24,
-0x3c,0x09,0x00,0x01,0x35,0x29,0x7f,0xff,0x4c,0x8a,0x20,0x00,0x4c,0x89,0x28,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x08,0x04,0x10,
-0x00,0x00,0x00,0x00,0x40,0x88,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x3c,0x08,0xbf,0xc0,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,
-0x3c,0x0a,0xbf,0xc0,0x25,0x4a,0x01,0x20,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,
-0x3c,0x08,0xb0,0x03,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x29,0x00,0x10,
-0xad,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x00,0x25,0x08,0x4b,0x94,
-0x01,0x00,0x00,0x08,0x00,0x00,0x00,0x00,};
-
-u8 Rtl8192PciEFwMainArray[MainArrayLengthPciE] = {
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x40,0x04,0x68,0x00,0x40,0x05,0x70,0x00,0x40,0x06,0x40,0x00,0x0c,0x00,0x12,0x98,
-0x00,0x00,0x00,0x00,0x40,0x1a,0x68,0x00,0x33,0x5b,0x00,0x3c,0x17,0x60,0x00,0x09,
-0x00,0x00,0x00,0x00,0x40,0x1b,0x60,0x00,0x00,0x00,0x00,0x00,0x03,0x5b,0xd0,0x24,
-0x40,0x1a,0x70,0x00,0x03,0x40,0x00,0x08,0x42,0x00,0x00,0x10,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0xff,0xff,0x8c,0x43,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x00,0xd0,
-0xac,0x62,0x00,0x00,0x00,0x00,0x20,0x21,0x27,0x85,0x8b,0x70,0x00,0x85,0x18,0x21,
-0x24,0x84,0x00,0x01,0x28,0x82,0x00,0x0a,0x14,0x40,0xff,0xfc,0xa0,0x60,0x00,0x00,
-0x27,0x82,0x8b,0x7a,0x24,0x04,0x00,0x06,0x24,0x84,0xff,0xff,0xa4,0x40,0x00,0x00,
-0x04,0x81,0xff,0xfd,0x24,0x42,0x00,0x02,0x24,0x02,0x00,0x03,0xa3,0x82,0x8b,0x70,
-0x24,0x02,0x00,0x0a,0x24,0x03,0x09,0xc4,0xa3,0x82,0x8b,0x72,0x24,0x02,0x00,0x04,
-0x24,0x04,0x00,0x01,0x24,0x05,0x00,0x02,0xa7,0x83,0x8b,0x86,0xa3,0x82,0x8b,0x78,
-0x24,0x03,0x04,0x00,0x24,0x02,0x02,0x00,0xaf,0x83,0x8b,0x8c,0xa3,0x85,0x8b,0x79,
-0xa7,0x82,0x8b,0x7a,0xa7,0x84,0x8b,0x7c,0xaf,0x84,0x8b,0x88,0xa3,0x84,0x8b,0x71,
-0xa3,0x80,0x8b,0x73,0xa3,0x80,0x8b,0x74,0xa3,0x80,0x8b,0x75,0xa3,0x84,0x8b,0x76,
-0xa3,0x85,0x8b,0x77,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x24,0x42,0x01,0x7c,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,
-0x27,0x84,0x8b,0x98,0x00,0x00,0x10,0x21,0x24,0x42,0x00,0x01,0x00,0x02,0x16,0x00,
-0x00,0x02,0x16,0x03,0x28,0x43,0x00,0x03,0xac,0x80,0xff,0xfc,0xa0,0x80,0x00,0x00,
-0x14,0x60,0xff,0xf9,0x24,0x84,0x00,0x0c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x01,0xc0,
-0x3c,0x08,0xb0,0x03,0xac,0x62,0x00,0x00,0x35,0x08,0x00,0x70,0x8d,0x02,0x00,0x00,
-0x00,0xa0,0x48,0x21,0x00,0x04,0x26,0x00,0x00,0x02,0x2a,0x43,0x00,0x06,0x36,0x00,
-0x00,0x07,0x3e,0x00,0x00,0x02,0x12,0x03,0x29,0x23,0x00,0x03,0x00,0x04,0x56,0x03,
-0x00,0x06,0x36,0x03,0x00,0x07,0x3e,0x03,0x30,0x48,0x00,0x01,0x10,0x60,0x00,0x11,
-0x30,0xa5,0x00,0x07,0x24,0x02,0x00,0x02,0x00,0x49,0x10,0x23,0x00,0x45,0x10,0x07,
-0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x66,0x00,0x00,0x00,0x00,0x8f,0xa2,0x00,0x10,
-0x00,0x00,0x00,0x00,0x00,0x02,0x21,0x43,0x11,0x00,0x00,0x10,0x00,0x07,0x20,0x0b,
-0x15,0x20,0x00,0x06,0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x05,0x34,0x42,0x01,0x20,
-0xa4,0x44,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x11,0x22,0x00,0x04,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x94,0x34,0x42,0x01,0x24,
-0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x94,0x34,0x42,0x01,0x22,0x15,0x20,0x00,0x54,
-0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x74,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0x94,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x70,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x6b,0x00,0x08,0x11,0x60,0x00,0x18,
-0x00,0x09,0x28,0x40,0x00,0x00,0x40,0x21,0x27,0x85,0x8b,0x90,0x8c,0xa3,0x00,0x00,
-0x8c,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x62,0x38,0x23,0x00,0x43,0x10,0x2a,
-0x10,0x40,0x00,0x3d,0x00,0x00,0x00,0x00,0xac,0xa7,0x00,0x00,0x25,0x02,0x00,0x01,
-0x00,0x02,0x16,0x00,0x00,0x02,0x46,0x03,0x29,0x03,0x00,0x03,0x14,0x60,0xff,0xf3,
-0x24,0xa5,0x00,0x0c,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x70,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x4b,0x10,0x23,0xa0,0x62,0x00,0x00,0x00,0x09,0x28,0x40,
-0x00,0xa9,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x8b,0x98,0x00,0x0a,0x20,0x0b,
-0x00,0x43,0x18,0x21,0x10,0xc0,0x00,0x05,0x00,0x00,0x38,0x21,0x80,0x62,0x00,0x01,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x80,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0xa9,0x10,0x21,0x24,0x07,0x00,0x01,
-0x00,0xa9,0x10,0x21,0x00,0x02,0x30,0x80,0x27,0x82,0x8b,0x98,0xa0,0x67,0x00,0x01,
-0x00,0xc2,0x38,0x21,0x80,0xe3,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x07,
-0x00,0x00,0x00,0x00,0x27,0x83,0x8b,0x90,0x00,0xc3,0x18,0x21,0x8c,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x21,0xac,0x62,0x00,0x00,0x27,0x85,0x8b,0x94,
-0x27,0x82,0x8b,0x90,0x00,0xc5,0x28,0x21,0x00,0xc2,0x10,0x21,0x8c,0x43,0x00,0x00,
-0x8c,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x2a,0x14,0x60,0x00,0x03,
-0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0xa0,0xe2,0x00,0x00,0xa0,0xe0,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0xb7,0xac,0xa0,0x00,0x00,
-0x11,0x22,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x7c,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0xac,0x08,0x00,0x00,0xa7,
-0x3c,0x02,0xb0,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x78,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0xa0,0x08,0x00,0x00,0xa7,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x04,0x10,
-0x3c,0x05,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0xa5,0x00,0x70,0x8c,0xa2,0x00,0x00,
-0x90,0x84,0x00,0x08,0x3c,0x06,0xb0,0x03,0x00,0x02,0x16,0x00,0x2c,0x83,0x00,0x03,
-0x34,0xc6,0x00,0x72,0x24,0x07,0x00,0x01,0x10,0x60,0x00,0x11,0x00,0x02,0x2f,0xc2,
-0x90,0xc2,0x00,0x00,0x00,0x00,0x18,0x21,0x00,0x02,0x16,0x00,0x10,0xa7,0x00,0x09,
-0x00,0x02,0x16,0x03,0x14,0x80,0x00,0x0c,0x30,0x43,0x00,0x03,0x83,0x82,0x8b,0x98,
-0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0x02,0x16,0x00,
-0x00,0x02,0x1e,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x72,0xa0,0x43,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0x45,0x00,0x05,0x10,0x87,0x00,0x04,
-0x30,0x43,0x00,0x06,0x93,0x82,0x8b,0xb0,0x08,0x00,0x01,0x1f,0x00,0x43,0x10,0x21,
-0x83,0x82,0x8b,0xa4,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x40,0x08,0x00,0x01,0x1f,
-0x00,0x45,0x10,0x21,0x10,0x80,0x00,0x05,0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01,
-0x00,0x64,0x10,0x2b,0x14,0x40,0xff,0xfd,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x04,0xe4,
-0x3c,0x04,0xb0,0x02,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x08,
-0x24,0x02,0x00,0x01,0xaf,0x84,0x8b,0xc0,0xa3,0x82,0x8b,0xd0,0xa7,0x80,0x8b,0xc4,
-0xa7,0x80,0x8b,0xc6,0xaf,0x80,0x8b,0xc8,0xaf,0x80,0x8b,0xcc,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,
-0x24,0x42,0x05,0x24,0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0xac,
-0x80,0xa2,0x00,0x15,0x8c,0x83,0x00,0x00,0x27,0xbd,0xff,0xf0,0x00,0x43,0x10,0x21,
-0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x10,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0x80,0x00,0x34,0x42,0x00,0x20,0x24,0x63,0x05,0x5c,0x27,0xbd,0xff,0xe0,
-0xac,0x43,0x00,0x00,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18,
-0x8f,0x90,0x8b,0xc0,0x0c,0x00,0x02,0x98,0x00,0x80,0x88,0x21,0x14,0x40,0x00,0x2a,
-0x3c,0x02,0x00,0x80,0x16,0x20,0x00,0x02,0x34,0x42,0x02,0x01,0x24,0x02,0x02,0x01,
-0xae,0x02,0x00,0x00,0x97,0x84,0x8b,0xc4,0x97,0x82,0x8b,0xc6,0x3c,0x03,0xb0,0x02,
-0x00,0x83,0x20,0x21,0x24,0x42,0x00,0x04,0xa7,0x82,0x8b,0xc6,0xa4,0x82,0x00,0x00,
-0x8f,0x84,0x8b,0xc8,0x8f,0x82,0x8b,0xc0,0x93,0x85,0x8b,0x72,0x24,0x84,0x00,0x01,
-0x24,0x42,0x00,0x04,0x24,0x03,0x8f,0xff,0x3c,0x07,0xb0,0x06,0x3c,0x06,0xb0,0x03,
-0x00,0x43,0x10,0x24,0x00,0x85,0x28,0x2a,0x34,0xe7,0x80,0x18,0xaf,0x82,0x8b,0xc0,
-0xaf,0x84,0x8b,0xc8,0x10,0xa0,0x00,0x08,0x34,0xc6,0x01,0x08,0x8f,0x83,0x8b,0xcc,
-0x8f,0x84,0x8b,0x8c,0x8c,0xc2,0x00,0x00,0x00,0x64,0x18,0x21,0x00,0x43,0x10,0x2b,
-0x14,0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x8c,0xe2,0x00,0x00,0x3c,0x03,0x0f,0x00,
-0x3c,0x04,0x04,0x00,0x00,0x43,0x10,0x24,0x10,0x44,0x00,0x03,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0x80,0x00,0x24,0x63,0x06,0x48,0xaf,0xb0,0x00,0x10,0x34,0x42,0x00,0x20,
-0x8f,0x90,0x8b,0xc0,0xac,0x43,0x00,0x00,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,
-0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0x00,0x80,0x88,0x21,0x00,0xa0,0x90,0x21,
-0x0c,0x00,0x02,0x98,0x00,0xc0,0x98,0x21,0x24,0x07,0x8f,0xff,0x14,0x40,0x00,0x19,
-0x26,0x03,0x00,0x04,0x24,0x02,0x0e,0x03,0xae,0x02,0x00,0x00,0x00,0x67,0x80,0x24,
-0x26,0x02,0x00,0x04,0xae,0x11,0x00,0x00,0x00,0x47,0x80,0x24,0x97,0x86,0x8b,0xc4,
-0x26,0x03,0x00,0x04,0xae,0x12,0x00,0x00,0x00,0x67,0x80,0x24,0xae,0x13,0x00,0x00,
-0x8f,0x84,0x8b,0xc0,0x3c,0x02,0xb0,0x02,0x97,0x85,0x8b,0xc6,0x00,0xc2,0x30,0x21,
-0x8f,0x82,0x8b,0xc8,0x24,0x84,0x00,0x10,0x24,0xa5,0x00,0x10,0x00,0x87,0x20,0x24,
-0x24,0x42,0x00,0x01,0xa7,0x85,0x8b,0xc6,0xaf,0x84,0x8b,0xc0,0xaf,0x82,0x8b,0xc8,
-0xa4,0xc5,0x00,0x00,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,
-0x94,0x82,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0xe0,0x00,0x14,0x40,0x00,0x14,
-0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x02,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfc,
-0x00,0x82,0x28,0x21,0x8c,0xa4,0x00,0x00,0x3c,0x02,0x00,0x70,0x8c,0xa6,0x00,0x08,
-0x00,0x82,0x10,0x21,0x2c,0x43,0x00,0x06,0x10,0x60,0x00,0x09,0x3c,0x03,0x80,0x01,
-0x00,0x02,0x10,0x80,0x24,0x63,0x01,0xe8,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0xaf,0x86,0x80,0x14,
-0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
-0x8c,0xa4,0x00,0x00,0x0c,0x00,0x17,0x84,0x00,0x00,0x00,0x00,0x08,0x00,0x01,0xdc,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x24,0x49,0x00,0xc0,0x20,0x21,0x08,0x00,0x01,0xdc,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,
-0x8f,0x82,0x80,0x18,0x3c,0x03,0x00,0x0f,0x34,0x63,0x42,0x40,0x00,0x43,0x10,0x21,
-0x00,0x82,0x20,0x2b,0x10,0x80,0x00,0x09,0x24,0x03,0x00,0x05,0x8f,0x82,0x83,0x60,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x83,0x60,0x10,0x43,0x00,0x03,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x8c,0x63,0x01,0x08,0x24,0x02,0x00,0x01,0xa3,0x82,0x80,0x11,0xaf,0x80,0x83,0x60,
-0xaf,0x83,0x80,0x18,0x08,0x00,0x01,0xf9,0x00,0x00,0x00,0x00,0x30,0x84,0x00,0xff,
-0x14,0x80,0x00,0x2f,0x00,0x00,0x00,0x00,0x8f,0x82,0x80,0x14,0xa3,0x85,0x83,0x93,
-0x10,0x40,0x00,0x2b,0x2c,0xa2,0x00,0x04,0x14,0x40,0x00,0x06,0x00,0x05,0x10,0x40,
-0x24,0xa2,0xff,0xfc,0x2c,0x42,0x00,0x08,0x10,0x40,0x00,0x09,0x24,0xa2,0xff,0xf0,
-0x00,0x05,0x10,0x40,0x27,0x84,0x83,0x9c,0x00,0x44,0x10,0x21,0x94,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08,0xa4,0x43,0x00,0x00,
-0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x0a,0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xe0,
-0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x06,0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xd0,
-0x2c,0x42,0x00,0x10,0x10,0x40,0x00,0x09,0x24,0xa2,0xff,0xc0,0x00,0x05,0x10,0x40,
-0x27,0x84,0x83,0x9c,0x00,0x44,0x10,0x21,0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00,
-0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08,0xa4,0x43,0xff,0xf8,0x2c,0x42,0x00,0x10,
-0x10,0x40,0x00,0x07,0x00,0x05,0x10,0x40,0x27,0x84,0x83,0x9c,0x00,0x44,0x10,0x21,
-0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0xa4,0x43,0xff,0xf8,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0x86,0x8b,0xc0,0x8f,0x82,0x80,0x14,
-0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x10,0x40,0x00,0x2a,0x00,0xc0,0x38,0x21,
-0x24,0x02,0x00,0x07,0x24,0x03,0xff,0x9c,0xa3,0x82,0x83,0x9b,0xa3,0x83,0x83,0x9a,
-0x27,0x8a,0x83,0x98,0x00,0x00,0x20,0x21,0x24,0x09,0x8f,0xff,0x00,0x04,0x10,0x80,
-0x00,0x4a,0x28,0x21,0x8c,0xa2,0x00,0x00,0x24,0xe3,0x00,0x04,0x24,0x88,0x00,0x01,
-0xac,0xe2,0x00,0x00,0x10,0x80,0x00,0x02,0x00,0x69,0x38,0x24,0xac,0xa0,0x00,0x00,
-0x31,0x04,0x00,0xff,0x2c,0x82,0x00,0x27,0x14,0x40,0xff,0xf5,0x00,0x04,0x10,0x80,
-0x97,0x83,0x8b,0xc6,0x97,0x85,0x8b,0xc4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x9c,
-0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xc6,0x34,0x84,0x80,0x18,
-0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x9c,
-0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,
-0xaf,0x86,0x8b,0xc0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,
-0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x8f,0x86,0x8b,0xc0,0x27,0xbd,0xff,0xc8,0x24,0x02,0x00,0x08,
-0x24,0x03,0x00,0x20,0xaf,0xbf,0x00,0x30,0xa3,0xa2,0x00,0x13,0xa3,0xa3,0x00,0x12,
-0xa7,0xa4,0x00,0x10,0x00,0xc0,0x28,0x21,0x27,0xa9,0x00,0x10,0x00,0x00,0x38,0x21,
-0x24,0x08,0x8f,0xff,0x00,0x07,0x10,0x80,0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00,
-0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff,0x24,0xa2,0x00,0x04,0x2c,0xe3,0x00,0x08,
-0xac,0xa4,0x00,0x00,0x14,0x60,0xff,0xf7,0x00,0x48,0x28,0x24,0x97,0x83,0x8b,0xc6,
-0x97,0x85,0x8b,0xc4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x20,0x00,0xa2,0x28,0x21,
-0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xc6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,
-0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x20,0x3c,0x03,0x0f,0x00,
-0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xc0,
-0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00,
-0x8f,0xbf,0x00,0x30,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,
-0x93,0x82,0x8b,0xd0,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x11,0x24,0x06,0x00,0x01,
-0x8f,0x82,0x8b,0xc8,0x3c,0x05,0xb0,0x06,0x3c,0x04,0xb0,0x03,0x34,0xa5,0x80,0x18,
-0x34,0x84,0x01,0x08,0x14,0x40,0x00,0x09,0x00,0x00,0x30,0x21,0x97,0x82,0x8b,0xc4,
-0x8c,0x84,0x00,0x00,0x3c,0x03,0xb0,0x02,0x00,0x43,0x10,0x21,0xaf,0x84,0x8b,0xcc,
-0xa7,0x80,0x8b,0xc6,0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04,0x8c,0xa2,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0xc0,0x10,0x21,0x8f,0x86,0x8b,0xc0,0x8f,0x82,0x8b,0xc8,
-0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x00,0xc0,0x40,0x21,0x14,0x40,0x00,0x0a,
-0x00,0x40,0x50,0x21,0x00,0x00,0x38,0x21,0x27,0x89,0x83,0x68,0x24,0xe2,0x00,0x01,
-0x00,0x07,0x18,0x80,0x30,0x47,0x00,0xff,0x00,0x69,0x18,0x21,0x2c,0xe2,0x00,0x0a,
-0x14,0x40,0xff,0xfa,0xac,0x60,0x00,0x00,0x3c,0x02,0x00,0x80,0x10,0x82,0x00,0x6f,
-0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x6e,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,
-0xa7,0x82,0x83,0x6e,0x90,0xa3,0x00,0x15,0x97,0x82,0x83,0x70,0x00,0x03,0x1e,0x00,
-0x00,0x03,0x1e,0x03,0x00,0x43,0x10,0x21,0xa7,0x82,0x83,0x70,0x8c,0xa4,0x00,0x20,
-0x3c,0x02,0x00,0x60,0x3c,0x03,0x00,0x20,0x00,0x82,0x20,0x24,0x10,0x83,0x00,0x54,
-0x00,0x00,0x00,0x00,0x14,0x80,0x00,0x47,0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x74,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x74,0x84,0xa3,0x00,0x06,
-0x8f,0x82,0x83,0x84,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x84,
-0x25,0x42,0x00,0x01,0x28,0x43,0x27,0x10,0xaf,0x82,0x8b,0xc8,0x10,0x60,0x00,0x09,
-0x24,0x02,0x00,0x04,0x93,0x83,0x80,0x11,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x05,
-0x24,0x02,0x00,0x04,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x24,0x03,0x00,0x28,0xa3,0x83,0x83,0x6a,0xa3,0x82,0x83,0x6b,
-0x90,0xa2,0x00,0x18,0x93,0x83,0x83,0x93,0x00,0x00,0x38,0x21,0x00,0x02,0x16,0x00,
-0x00,0x02,0x16,0x03,0xa7,0x82,0x83,0x7e,0xa3,0x83,0x83,0x8c,0x27,0x89,0x83,0x68,
-0x24,0x05,0x8f,0xff,0x00,0x07,0x10,0x80,0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00,
-0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff,0x25,0x02,0x00,0x04,0x2c,0xe3,0x00,0x0a,
-0xad,0x04,0x00,0x00,0x14,0x60,0xff,0xf7,0x00,0x45,0x40,0x24,0x97,0x83,0x8b,0xc6,
-0x97,0x85,0x8b,0xc4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x28,0x00,0xa2,0x28,0x21,
-0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xc6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,
-0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x28,0x3c,0x03,0x0f,0x00,
-0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xc0,
-0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x02,0x36,0x00,0x00,0x00,0x00,0xa3,0x80,0x80,0x11,0x08,0x00,0x02,0xe5,
-0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x76,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,
-0xa7,0x82,0x83,0x76,0x84,0xa3,0x00,0x06,0x8f,0x82,0x83,0x88,0x00,0x00,0x00,0x00,
-0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x88,0x08,0x00,0x02,0xdd,0x25,0x42,0x00,0x01,
-0x97,0x82,0x83,0x72,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x72,
-0x84,0xa3,0x00,0x06,0x8f,0x82,0x83,0x80,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,
-0xaf,0x82,0x83,0x80,0x08,0x00,0x02,0xdd,0x25,0x42,0x00,0x01,0x97,0x82,0x83,0x6c,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x6c,0x08,0x00,0x02,0xc5,
-0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xd0,0xaf,0xbf,0x00,0x28,0x8c,0xa3,0x00,0x20,
-0x8f,0x8a,0x8b,0xc0,0x3c,0x02,0x00,0x10,0x00,0x62,0x10,0x24,0x00,0xa0,0x38,0x21,
-0x01,0x40,0x48,0x21,0x10,0x40,0x00,0x3d,0x00,0x80,0x28,0x21,0x8c,0xe4,0x00,0x1c,
-0x34,0xa5,0x12,0x06,0xaf,0xa5,0x00,0x10,0x8c,0x82,0x00,0x08,0x00,0x03,0x1c,0x42,
-0x30,0x63,0x00,0x30,0x00,0x02,0x13,0x02,0x30,0x42,0x00,0x40,0x00,0x43,0x10,0x25,
-0x90,0xe6,0x00,0x10,0x90,0xe4,0x00,0x13,0x94,0xe8,0x00,0x0c,0x94,0xe3,0x00,0x1a,
-0x00,0x02,0x16,0x00,0x90,0xe7,0x00,0x12,0x00,0xa2,0x28,0x25,0x24,0x02,0x12,0x34,
-0xa7,0xa2,0x00,0x1c,0x24,0x02,0x56,0x78,0xaf,0xa5,0x00,0x10,0xa3,0xa6,0x00,0x18,
-0xa3,0xa7,0x00,0x1f,0xa7,0xa3,0x00,0x1a,0xa3,0xa4,0x00,0x19,0xa7,0xa8,0x00,0x20,
-0xa7,0xa2,0x00,0x22,0x00,0x00,0x28,0x21,0x27,0xa7,0x00,0x10,0x24,0x06,0x8f,0xff,
-0x00,0x05,0x10,0x80,0x00,0x47,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xa3,0x00,0x01,
-0x30,0x65,0x00,0xff,0x25,0x22,0x00,0x04,0x2c,0xa3,0x00,0x05,0xad,0x24,0x00,0x00,
-0x14,0x60,0xff,0xf7,0x00,0x46,0x48,0x24,0x97,0x83,0x8b,0xc6,0x97,0x85,0x8b,0xc4,
-0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x14,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,
-0xa7,0x83,0x8b,0xc6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,
-0x24,0x02,0x8f,0xff,0x25,0x46,0x00,0x14,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x50,0x24,
-0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x8a,0x8b,0xc0,0x10,0xa2,0x00,0x03,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x28,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,0x3c,0x05,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8,0x00,0x04,0x22,0x00,0x34,0xa5,0x00,0x20,
-0x24,0x42,0x0d,0xfc,0x3c,0x03,0xb0,0x00,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,
-0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x30,0x00,0x83,0x80,0x21,
-0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,
-0xac,0xa2,0x00,0x00,0x8e,0x09,0x00,0x00,0x00,0x00,0x90,0x21,0x26,0x10,0x00,0x08,
-0x00,0x09,0xa6,0x02,0x12,0x80,0x00,0x13,0x00,0x00,0xa8,0x21,0x24,0x13,0x00,0x02,
-0x3c,0x16,0x00,0xff,0x3c,0x17,0xff,0x00,0x8e,0x09,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x09,0x12,0x02,0x24,0x42,0x00,0x02,0x31,0x25,0x00,0xff,0x10,0xb3,0x00,0x76,
-0x30,0x51,0x00,0xff,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x18,0x00,0x00,0x00,0x00,
-0x02,0x51,0x10,0x21,0x30,0x52,0xff,0xff,0x02,0x54,0x18,0x2b,0x14,0x60,0xff,0xf2,
-0x02,0x11,0x80,0x21,0x12,0xa0,0x00,0x0a,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18,
-0x8c,0x43,0x00,0x00,0x3c,0x04,0x0f,0x00,0x3c,0x02,0x04,0x00,0x00,0x64,0x18,0x24,
-0x10,0x62,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00,
-0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x8e,0x09,0x00,0x04,
-0x24,0x15,0x00,0x01,0x8e,0x06,0x00,0x0c,0x00,0x09,0x11,0x42,0x00,0x09,0x18,0xc2,
-0x30,0x48,0x00,0x03,0x00,0x09,0x14,0x02,0x30,0x6c,0x00,0x03,0x00,0x09,0x26,0x02,
-0x11,0x15,0x00,0x45,0x30,0x43,0x00,0x0f,0x29,0x02,0x00,0x02,0x14,0x40,0x00,0x26,
-0x00,0x00,0x00,0x00,0x11,0x13,0x00,0x0f,0x00,0x00,0x38,0x21,0x00,0x07,0x22,0x02,
-0x30,0x84,0xff,0x00,0x3c,0x03,0x00,0xff,0x00,0x07,0x2e,0x02,0x00,0x07,0x12,0x00,
-0x00,0x43,0x10,0x24,0x00,0xa4,0x28,0x25,0x00,0xa2,0x28,0x25,0x00,0x07,0x1e,0x00,
-0x00,0xa3,0x28,0x25,0x0c,0x00,0x01,0x92,0x01,0x20,0x20,0x21,0x08,0x00,0x03,0xa5,
-0x02,0x51,0x10,0x21,0x11,0x95,0x00,0x0f,0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x07,
-0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x80,0x27,0x83,0x8b,0x70,0x00,0x43,0x10,0x21,
-0x8c,0x47,0x00,0x18,0x08,0x00,0x03,0xcc,0x00,0x07,0x22,0x02,0x00,0x04,0x10,0x40,
-0x27,0x83,0x8b,0x78,0x00,0x43,0x10,0x21,0x94,0x47,0x00,0x02,0x08,0x00,0x03,0xcc,
-0x00,0x07,0x22,0x02,0x27,0x82,0x8b,0x70,0x00,0x82,0x10,0x21,0x90,0x47,0x00,0x00,
-0x08,0x00,0x03,0xcc,0x00,0x07,0x22,0x02,0x15,0x00,0xff,0xdc,0x00,0x00,0x38,0x21,
-0x10,0x75,0x00,0x05,0x00,0x80,0x38,0x21,0x00,0x65,0x18,0x26,0x24,0x82,0x01,0x00,
-0x00,0x00,0x38,0x21,0x00,0x43,0x38,0x0a,0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x0e,
-0x3c,0x02,0xb0,0x03,0x24,0x02,0x00,0x02,0x11,0x82,0x00,0x06,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x00,0xe2,0x10,0x21,0x8c,0x47,0x00,0x00,0x08,0x00,0x03,0xcc,
-0x00,0x07,0x22,0x02,0x3c,0x02,0xb0,0x03,0x00,0xe2,0x10,0x21,0x94,0x43,0x00,0x00,
-0x08,0x00,0x03,0xcb,0x30,0x67,0xff,0xff,0x00,0xe2,0x10,0x21,0x90,0x43,0x00,0x00,
-0x08,0x00,0x03,0xcb,0x30,0x67,0x00,0xff,0x30,0x62,0x00,0x03,0x00,0x02,0x12,0x00,
-0x11,0x95,0x00,0x07,0x00,0x44,0x38,0x21,0x11,0x93,0x00,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0x03,0xfd,0x3c,0x02,0xb0,0x0a,0x08,0x00,0x04,0x02,0x3c,0x02,0xb0,0x0a,
-0x08,0x00,0x04,0x06,0x3c,0x02,0xb0,0x0a,0x8e,0x09,0x00,0x04,0x8e,0x02,0x00,0x08,
-0x8e,0x03,0x00,0x0c,0x00,0x09,0x41,0x42,0x00,0x02,0x22,0x02,0x00,0x03,0x3a,0x02,
-0x30,0x84,0xff,0x00,0x30,0xe7,0xff,0x00,0x00,0x02,0x5e,0x02,0x00,0x02,0x32,0x00,
-0x00,0x03,0x56,0x02,0x00,0x03,0x2a,0x00,0x01,0x64,0x58,0x25,0x00,0xd6,0x30,0x24,
-0x01,0x47,0x50,0x25,0x00,0x02,0x16,0x00,0x00,0xb6,0x28,0x24,0x00,0x03,0x1e,0x00,
-0x01,0x66,0x58,0x25,0x01,0x45,0x50,0x25,0x00,0x57,0x10,0x24,0x00,0x77,0x18,0x24,
-0x01,0x62,0x38,0x25,0x01,0x43,0x30,0x25,0x00,0x09,0x10,0xc2,0x00,0x09,0x1c,0x02,
-0x31,0x08,0x00,0x03,0x30,0x4c,0x00,0x03,0x30,0x63,0x00,0x0f,0x00,0x09,0x26,0x02,
-0x00,0xe0,0x58,0x21,0x15,0x00,0x00,0x28,0x00,0xc0,0x50,0x21,0x24,0x02,0x00,0x01,
-0x10,0x62,0x00,0x06,0x00,0x80,0x28,0x21,0x24,0x02,0x00,0x03,0x14,0x62,0xff,0x69,
-0x02,0x51,0x10,0x21,0x24,0x85,0x01,0x00,0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x15,
-0x24,0x02,0x00,0x02,0x11,0x82,0x00,0x0a,0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21,
-0x8c,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,
-0x00,0x45,0x10,0x25,0xac,0x62,0x00,0x00,0x08,0x00,0x03,0xa5,0x02,0x51,0x10,0x21,
-0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,
-0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0xa4,0x62,0x00,0x00,0x08,0x00,0x03,0xa5,
-0x02,0x51,0x10,0x21,0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21,0x90,0x62,0x00,0x00,
-0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,
-0x08,0x00,0x03,0xa4,0xa0,0x62,0x00,0x00,0x24,0x02,0x00,0x01,0x11,0x02,0x00,0x21,
-0x00,0x00,0x00,0x00,0x15,0x13,0xff,0x42,0x00,0x00,0x00,0x00,0x11,0x82,0x00,0x17,
-0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x0b,0x00,0x00,0x00,0x00,0x27,0x83,0x8b,0x70,
-0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x18,0x00,0x06,0x18,0x27,
-0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa4,
-0xac,0x82,0x00,0x18,0x27,0x83,0x8b,0x78,0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x21,
-0x94,0x82,0x00,0x02,0x00,0x06,0x18,0x27,0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24,
-0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa4,0xa4,0x82,0x00,0x02,0x27,0x83,0x8b,0x70,
-0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x5a,
-0x00,0xe6,0x28,0x24,0x30,0x62,0x00,0x07,0x00,0x02,0x12,0x00,0x11,0x88,0x00,0x0f,
-0x00,0x44,0x10,0x21,0x11,0x93,0x00,0x07,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a,
-0x00,0x43,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x47,
-0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a,0x00,0x43,0x18,0x21,0x94,0x62,0x00,0x00,
-0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x50,0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a,
-0x08,0x00,0x04,0x7d,0x00,0x43,0x18,0x21,0x97,0x85,0x8b,0xc4,0x3c,0x07,0xb0,0x02,
-0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x00,0x00,0xa7,0x28,0x21,0x34,0x84,0x00,0x20,
-0x24,0x42,0x12,0x58,0x24,0x03,0xff,0x80,0xac,0x82,0x00,0x00,0xa0,0xa3,0x00,0x07,
-0x97,0x82,0x8b,0xc6,0x97,0x85,0x8b,0xc4,0x3c,0x06,0xb0,0x06,0x30,0x42,0xff,0xf8,
-0x24,0x42,0x00,0x10,0x00,0xa2,0x10,0x21,0x30,0x42,0x0f,0xff,0x24,0x44,0x00,0x08,
-0x30,0x84,0x0f,0xff,0x00,0x05,0x28,0xc2,0x3c,0x03,0x00,0x40,0x00,0xa3,0x28,0x25,
-0x00,0x87,0x20,0x21,0x34,0xc6,0x80,0x18,0xac,0xc5,0x00,0x00,0xaf,0x84,0x8b,0xc0,
-0xa7,0x82,0x8b,0xc4,0xa7,0x80,0x8b,0xc6,0xaf,0x80,0x8b,0xc8,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x30,0x84,0x00,0xff,0x24,0x02,0x00,0x01,
-0x00,0xe0,0x48,0x21,0x30,0xc6,0x00,0xff,0x8f,0xa7,0x00,0x10,0x10,0x82,0x00,0x07,
-0x00,0xa0,0x40,0x21,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0x03,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x24,0xa8,0x01,0x00,0x3c,0x03,0xb0,0x03,
-0x24,0x02,0x00,0x01,0x00,0x07,0x20,0x27,0x01,0x27,0x28,0x24,0x10,0xc2,0x00,0x14,
-0x01,0x03,0x18,0x21,0x24,0x02,0x00,0x02,0x10,0xc2,0x00,0x09,0x00,0x07,0x50,0x27,
-0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x04,0xe1,0xac,0x62,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xa4,0x62,0x00,0x00,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,
-0xa0,0x62,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0x84,0x00,0x07,
-0x00,0x04,0x22,0x00,0x30,0xa5,0x00,0xff,0x00,0x85,0x28,0x21,0x3c,0x02,0xb0,0x0a,
-0x00,0xa2,0x40,0x21,0x30,0xc6,0x00,0xff,0x24,0x02,0x00,0x01,0x8f,0xa4,0x00,0x10,
-0x10,0xc2,0x00,0x14,0x24,0x02,0x00,0x02,0x00,0x04,0x50,0x27,0x10,0xc2,0x00,0x09,
-0x00,0xe4,0x48,0x24,0x3c,0x03,0xb0,0x0a,0x00,0xa3,0x18,0x21,0x8c,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08,
-0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08,
-0xa4,0x62,0x00,0x00,0x91,0x02,0x00,0x00,0x00,0x04,0x18,0x27,0x00,0xe4,0x20,0x24,
-0x00,0x43,0x10,0x24,0x00,0x44,0x10,0x25,0x03,0xe0,0x00,0x08,0xa1,0x02,0x00,0x00,
-0x30,0xa9,0x00,0xff,0x27,0x83,0x8b,0x70,0x30,0x85,0x00,0xff,0x24,0x02,0x00,0x01,
-0x00,0x07,0x50,0x27,0x00,0xc7,0x40,0x24,0x11,0x22,0x00,0x17,0x00,0xa3,0x18,0x21,
-0x00,0x05,0x20,0x40,0x27,0x82,0x8b,0x70,0x00,0x05,0x28,0x80,0x27,0x83,0x8b,0x78,
-0x00,0x83,0x50,0x21,0x00,0xa2,0x20,0x21,0x24,0x02,0x00,0x02,0x00,0x07,0x40,0x27,
-0x11,0x22,0x00,0x07,0x00,0xc7,0x28,0x24,0x8c,0x82,0x00,0x18,0x00,0x00,0x00,0x00,
-0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x18,
-0x95,0x42,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25,
-0x03,0xe0,0x00,0x08,0xa5,0x42,0x00,0x02,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x4a,0x10,0x24,0x00,0x48,0x10,0x25,0x03,0xe0,0x00,0x08,0xa0,0x62,0x00,0x00,
-0x00,0x04,0x32,0x02,0x30,0xc6,0xff,0x00,0x00,0x04,0x16,0x02,0x00,0x04,0x1a,0x00,
-0x3c,0x05,0x00,0xff,0x00,0x65,0x18,0x24,0x00,0x46,0x10,0x25,0x00,0x43,0x10,0x25,
-0x00,0x04,0x26,0x00,0x03,0xe0,0x00,0x08,0x00,0x44,0x10,0x25,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xe8,0x34,0x63,0x00,0x20,0x24,0x42,0x14,0xdc,
-0x3c,0x04,0xb0,0x03,0xaf,0xbf,0x00,0x14,0xac,0x62,0x00,0x00,0xaf,0xb0,0x00,0x10,
-0x34,0x84,0x00,0x2c,0x8c,0x83,0x00,0x00,0xa7,0x80,0xbc,0x00,0x00,0x03,0x12,0x02,
-0x00,0x03,0x2d,0x02,0x30,0x42,0x0f,0xff,0xa3,0x83,0xbc,0x08,0xa7,0x85,0xbc,0x0c,
-0xa7,0x82,0xbc,0x0a,0xa7,0x80,0xbc,0x02,0xa7,0x80,0xbc,0x04,0xa7,0x80,0xbc,0x06,
-0x0c,0x00,0x06,0xd1,0x24,0x04,0x05,0x00,0x3c,0x05,0x08,0x00,0x00,0x45,0x28,0x25,
-0x24,0x04,0x05,0x00,0x0c,0x00,0x06,0xbf,0x00,0x40,0x80,0x21,0x3c,0x02,0xf7,0xff,
-0x34,0x42,0xff,0xff,0x02,0x02,0x80,0x24,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xbf,
-0x24,0x04,0x05,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x03,0x34,0x42,0x01,0x08,
-0x34,0x63,0x01,0x18,0x8c,0x45,0x00,0x00,0x8c,0x64,0x00,0x00,0x3c,0x02,0x00,0x0f,
-0x3c,0x03,0x00,0x4c,0x30,0x84,0x02,0x00,0x34,0x63,0x4b,0x40,0xaf,0x85,0xbc,0x10,
-0x10,0x80,0x00,0x06,0x34,0x42,0x42,0x40,0xaf,0x83,0xbc,0x14,0x8f,0xbf,0x00,0x14,
-0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0xaf,0x82,0xbc,0x14,
-0x08,0x00,0x05,0x67,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x27,0xbd,0xff,0xc8,0x34,0x63,0x00,0x20,0x24,0x42,0x15,0xb8,0x30,0x84,0x00,0xff,
-0xaf,0xbf,0x00,0x30,0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,
-0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,
-0xaf,0xb0,0x00,0x10,0xac,0x62,0x00,0x00,0x10,0x80,0x00,0x1c,0x24,0x02,0x00,0x02,
-0x10,0x82,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c,
-0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x38,0xa7,0x80,0xbc,0x00,0xa7,0x80,0xbc,0x02,0xa7,0x80,0xbc,0x04,
-0xa7,0x80,0xbc,0x06,0x0c,0x00,0x06,0xd1,0x24,0x04,0x05,0x00,0x3c,0x05,0x08,0x00,
-0x00,0x45,0x28,0x25,0x24,0x04,0x05,0x00,0x0c,0x00,0x06,0xbf,0x00,0x40,0x80,0x21,
-0x3c,0x05,0xf7,0xff,0x34,0xa5,0xff,0xff,0x02,0x05,0x28,0x24,0x0c,0x00,0x06,0xbf,
-0x24,0x04,0x05,0x00,0x08,0x00,0x05,0x82,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1,
-0x24,0x04,0x05,0xa0,0x24,0x04,0x05,0xa4,0x0c,0x00,0x06,0xd1,0x00,0x02,0xbc,0x02,
-0x24,0x04,0x05,0xa8,0x00,0x02,0xb4,0x02,0x0c,0x00,0x06,0xd1,0x30,0x55,0xff,0xff,
-0x00,0x40,0x80,0x21,0x97,0x84,0xbc,0x00,0x97,0x82,0xbc,0x02,0x97,0x83,0xbc,0x06,
-0x02,0xe4,0x20,0x23,0x02,0xa2,0x10,0x23,0x00,0x82,0x20,0x21,0x97,0x82,0xbc,0x04,
-0x32,0x14,0xff,0xff,0x02,0x83,0x18,0x23,0x02,0xc2,0x10,0x23,0x00,0x82,0x20,0x21,
-0x93,0x82,0xbc,0x08,0x00,0x83,0x20,0x21,0x30,0x84,0xff,0xff,0x00,0x82,0x10,0x2b,
-0x14,0x40,0x00,0xaa,0x00,0x00,0x00,0x00,0x97,0x82,0xbc,0x0c,0x00,0x00,0x00,0x00,
-0x00,0x44,0x10,0x2b,0x14,0x40,0x00,0x7f,0x00,0x00,0x00,0x00,0x97,0x82,0xbc,0x0a,
-0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b,0x10,0x40,0x00,0x3a,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,0x00,0x40,0x80,0x21,
-0x2e,0x22,0x00,0x32,0x10,0x40,0x00,0x13,0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x17,
-0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,0x26,0x31,0x00,0x01,0x00,0x51,0x80,0x25,
-0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x50,0x02,0x00,0x28,0x21,
-0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x58,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xbf,
-0x24,0x04,0x04,0x60,0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x68,0x0c,0x00,0x06,0xbf,
-0x00,0x00,0x00,0x00,0xa7,0x97,0xbc,0x00,0xa7,0x95,0xbc,0x02,0xa7,0x96,0xbc,0x04,
-0xa7,0x94,0xbc,0x06,0x08,0x00,0x05,0x82,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1,
-0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,
-0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03,0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,
-0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x08,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x2c,
-0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,
-0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x2c,0x08,0x00,0x05,0xc9,
-0x24,0x02,0xff,0x80,0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,
-0x24,0x02,0x00,0x20,0x16,0x22,0xff,0xdb,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1,
-0x24,0x04,0x02,0x2c,0x34,0x52,0x40,0x00,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,
-0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x58,0x24,0x04,0x02,0x5c,
-0x0c,0x00,0x06,0xd1,0x00,0x02,0x9e,0x02,0x30,0x43,0x00,0xff,0x00,0x13,0x12,0x00,
-0x00,0x43,0x10,0x25,0x2c,0x43,0x00,0x04,0x14,0x60,0x00,0x1d,0x2c,0x42,0x00,0x11,
-0x10,0x40,0x00,0x0b,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,
-0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xbf,
-0x36,0x52,0x80,0x00,0x02,0x40,0x28,0x21,0x08,0x00,0x05,0xd7,0x24,0x04,0x02,0x2c,
-0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,
-0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x02,0x14,0x43,0xff,0xee,
-0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,
-0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x08,0x08,0x00,0x06,0x13,0x3c,0x02,0xff,0xff,
-0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82,
-0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03,0x14,0x43,0xff,0xdf,0x3c,0x02,0xff,0x3f,
-0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x3c,0x03,0x00,0x80,0x08,0x00,0x06,0x28,
-0x00,0x43,0x28,0x25,0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,
-0x00,0x40,0x80,0x21,0x2e,0x22,0x00,0x32,0x10,0x40,0xff,0x9a,0x24,0x02,0x00,0x20,
-0x12,0x22,0x00,0x04,0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,0x08,0x00,0x05,0xcb,
-0x26,0x31,0x00,0x02,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,
-0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03,
-0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,
-0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x08,
-0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x2c,0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,
-0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,
-0x24,0x04,0x02,0x2c,0x08,0x00,0x06,0x42,0x24,0x02,0xff,0x80,0x0c,0x00,0x06,0xd1,
-0x24,0x04,0x04,0x50,0x00,0x40,0x80,0x21,0x30,0x51,0x00,0x7f,0x24,0x02,0x00,0x20,
-0x12,0x22,0x00,0x1d,0x2e,0x22,0x00,0x21,0x14,0x40,0xff,0x72,0x24,0x02,0xff,0x80,
-0x02,0x02,0x10,0x24,0x26,0x31,0xff,0xff,0x00,0x51,0x80,0x25,0x24,0x04,0x04,0x50,
-0x0c,0x00,0x06,0xbf,0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x58,0x0c,0x00,0x06,0xbf,
-0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x60,0x0c,0x00,0x06,0xbf,0x02,0x00,0x28,0x21,
-0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x68,0x24,0x02,0x00,0x20,
-0x16,0x22,0xff,0x60,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x2c,
-0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x10,0x24,
-0x08,0x00,0x06,0x19,0x34,0x52,0x80,0x00,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x2c,
-0x34,0x52,0x40,0x00,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x2c,
-0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x58,0x24,0x04,0x02,0x5c,0x0c,0x00,0x06,0xd1,
-0x00,0x02,0x9e,0x02,0x30,0x43,0x00,0xff,0x00,0x13,0x12,0x00,0x00,0x43,0x10,0x25,
-0x2c,0x43,0x00,0x04,0x14,0x60,0x00,0x20,0x2c,0x42,0x00,0x11,0x10,0x40,0x00,0x0d,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,
-0x02,0x40,0x28,0x21,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xbf,0x36,0x52,0x80,0x00,
-0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x2c,0x08,0x00,0x06,0x66,
-0x2e,0x22,0x00,0x21,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,
-0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x02,
-0x14,0x43,0xff,0xec,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,
-0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x08,
-0x08,0x00,0x06,0x96,0x3c,0x02,0xff,0xff,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,
-0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82,0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03,
-0x14,0x43,0xff,0xdc,0x3c,0x03,0x00,0x80,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,
-0x00,0xa2,0x10,0x24,0x08,0x00,0x06,0xae,0x00,0x43,0x28,0x25,0x30,0x83,0x00,0x03,
-0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x23,0x3c,0x02,0xb0,0x0a,0x00,0x82,0x20,0x21,
-0x3c,0x06,0x00,0x01,0xac,0x85,0x00,0x00,0x24,0x07,0x00,0x01,0x00,0x00,0x28,0x21,
-0x34,0xc6,0x86,0x9f,0x8c,0x82,0x10,0x00,0x24,0xa5,0x00,0x01,0x10,0x47,0x00,0x03,
-0x00,0xc5,0x18,0x2b,0x10,0x60,0xff,0xfb,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x30,0x83,0x00,0x03,0x00,0x04,0x20,0x40,0x3c,0x02,0xb0,0x0a,
-0x00,0x83,0x20,0x23,0x00,0x82,0x20,0x21,0x3c,0x06,0x00,0x01,0x24,0x02,0xff,0xff,
-0xac,0x82,0x10,0x00,0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x01,0x34,0xc6,0x86,0x9f,
-0x8c,0x82,0x10,0x00,0x24,0xa5,0x00,0x01,0x10,0x47,0x00,0x03,0x00,0xc5,0x18,0x2b,
-0x10,0x60,0xff,0xfb,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x1b,0x94,
-0x24,0x03,0x00,0x01,0x34,0xa5,0x00,0x20,0x3c,0x06,0xb0,0x03,0xac,0xa2,0x00,0x00,
-0x34,0xc6,0x01,0x04,0xa0,0x83,0x00,0x48,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05,
-0xa0,0x80,0x00,0x06,0xa0,0x80,0x00,0x07,0xa0,0x80,0x00,0x08,0xa0,0x80,0x00,0x09,
-0xa0,0x80,0x00,0x0a,0xa0,0x80,0x00,0x11,0xa0,0x80,0x00,0x13,0xa0,0x80,0x00,0x49,
-0x94,0xc2,0x00,0x00,0xac,0x80,0x00,0x00,0xa0,0x80,0x00,0x4e,0x00,0x02,0x14,0x00,
-0x00,0x02,0x14,0x03,0x30,0x43,0x00,0xff,0x30,0x42,0xff,0x00,0xa4,0x82,0x00,0x44,
-0xa4,0x83,0x00,0x46,0xac,0x80,0x00,0x24,0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c,
-0xac,0x80,0x00,0x30,0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xac,0x80,0x00,0x3c,
-0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x40,0x84,0x83,0x00,0x0c,0x3c,0x07,0xb0,0x03,
-0x34,0xe7,0x00,0x20,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x90,0x04,0x00,0x43,0x10,0x21,0x8c,0x48,0x00,0x18,0x3c,0x02,0x80,0x00,
-0x24,0x42,0x1c,0x28,0xac,0xe2,0x00,0x00,0x8d,0x03,0x00,0x08,0x80,0x82,0x00,0x13,
-0x00,0x05,0x2c,0x00,0x00,0x03,0x1e,0x02,0x00,0x02,0x12,0x00,0x30,0x63,0x00,0x7e,
-0x00,0x62,0x18,0x21,0x00,0x65,0x18,0x21,0x3c,0x02,0xc0,0x00,0x3c,0x05,0xb0,0x05,
-0x34,0x42,0x04,0x00,0x24,0x63,0x00,0x01,0x3c,0x07,0xb0,0x05,0x3c,0x08,0xb0,0x05,
-0x34,0xa5,0x04,0x20,0xac,0xa3,0x00,0x00,0x00,0xc2,0x30,0x21,0x34,0xe7,0x04,0x24,
-0x35,0x08,0x02,0x28,0x24,0x02,0x00,0x01,0x24,0x03,0x00,0x20,0xac,0xe6,0x00,0x00,
-0xac,0x82,0x00,0x3c,0x03,0xe0,0x00,0x08,0xa1,0x03,0x00,0x00,0x27,0xbd,0xff,0xa8,
-0x00,0x07,0x60,0x80,0x27,0x82,0xb4,0x00,0xaf,0xbe,0x00,0x50,0xaf,0xb7,0x00,0x4c,
-0xaf,0xb5,0x00,0x44,0xaf,0xb4,0x00,0x40,0xaf,0xbf,0x00,0x54,0xaf,0xb6,0x00,0x48,
-0xaf,0xb3,0x00,0x3c,0xaf,0xb2,0x00,0x38,0xaf,0xb1,0x00,0x34,0xaf,0xb0,0x00,0x30,
-0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0xe0,0x70,0x21,0x3c,0x02,0x80,0x00,
-0x94,0x73,0x00,0x14,0x3c,0x07,0xb0,0x03,0x34,0xe7,0x00,0x20,0x24,0x42,0x1c,0xbc,
-0x3c,0x03,0xb0,0x05,0xac,0xe2,0x00,0x00,0x34,0x63,0x01,0x28,0x90,0x67,0x00,0x00,
-0x00,0x13,0xa8,0xc0,0x02,0xb3,0x18,0x21,0x27,0x82,0x90,0x04,0x00,0x03,0x18,0x80,
-0x00,0x62,0x18,0x21,0x00,0x05,0x2c,0x00,0x00,0x07,0x3e,0x00,0x28,0xc2,0x00,0x03,
-0x00,0xc0,0xa0,0x21,0x00,0x80,0x78,0x21,0x00,0x05,0xbc,0x03,0x8c,0x68,0x00,0x18,
-0x02,0xa0,0x58,0x21,0x10,0x40,0x01,0x81,0x00,0x07,0xf6,0x03,0x00,0xde,0x10,0x07,
-0x30,0x5e,0x00,0x01,0x01,0x73,0x10,0x21,0x27,0x83,0x90,0x08,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x80,0x4d,0x00,0x06,0x8d,0x03,0x00,0x00,0x8d,0x02,0x00,0x04,
-0x8d,0x0a,0x00,0x08,0x8d,0x03,0x00,0x0c,0xaf,0xa2,0x00,0x20,0x11,0xa0,0x01,0x71,
-0xaf,0xa3,0x00,0x18,0x27,0x82,0xb4,0x00,0x01,0x82,0x10,0x21,0x8c,0x44,0x00,0x00,
-0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x04,
-0x14,0x60,0x00,0x12,0x00,0x00,0xb0,0x21,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x46,
-0x90,0x43,0x00,0x00,0x2a,0x84,0x00,0x04,0x10,0x80,0x01,0x56,0x30,0x65,0x00,0x01,
-0x91,0xe2,0x00,0x09,0x00,0x00,0x00,0x00,0x12,0x82,0x00,0x02,0x00,0x00,0x00,0x00,
-0x00,0x00,0x28,0x21,0x14,0xa0,0x00,0x03,0x00,0x00,0x38,0x21,0x13,0xc0,0x00,0x03,
-0x38,0xf6,0x00,0x01,0x24,0x07,0x00,0x01,0x38,0xf6,0x00,0x01,0x01,0x73,0x10,0x21,
-0x00,0x02,0x30,0x80,0x27,0x83,0x90,0x10,0x00,0xc3,0x48,0x21,0x91,0x25,0x00,0x00,
-0x8f,0xa4,0x00,0x20,0x2c,0xa3,0x00,0x04,0x00,0x04,0x11,0xc3,0x30,0x42,0x00,0x01,
-0x00,0x03,0xb0,0x0b,0x12,0xc0,0x00,0xd8,0xaf,0xa2,0x00,0x24,0x93,0x90,0xbb,0xea,
-0x00,0x0a,0x16,0x42,0x30,0x52,0x00,0x3f,0x2e,0x06,0x00,0x0c,0x10,0xc0,0x00,0xc0,
-0x00,0xa0,0x20,0x21,0x2c,0xa2,0x00,0x10,0x14,0x40,0x00,0x04,0x00,0x90,0x10,0x2b,
-0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x04,0x00,0x90,0x10,0x2b,0x10,0x40,0x00,0x0b,
-0x01,0x73,0x10,0x21,0x27,0x85,0xbb,0x1c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21,
-0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b,
-0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x01,0x73,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x90,0x08,0x00,0x43,0x10,0x21,0x31,0xa4,0x00,0x01,0x10,0x80,0x00,0xa5,
-0xa0,0x50,0x00,0x07,0x3c,0x04,0xb0,0x05,0x34,0x84,0x00,0x08,0x24,0x02,0x00,0x01,
-0x3c,0x03,0x80,0x00,0xa1,0xe2,0x00,0x4e,0xac,0x83,0x00,0x00,0x8c,0x85,0x00,0x00,
-0x3c,0x02,0x00,0xf0,0x3c,0x03,0x40,0xf0,0x34,0x42,0xf0,0x00,0x34,0x63,0xf0,0x00,
-0x24,0x17,0x00,0x0e,0x24,0x13,0x01,0x06,0xac,0x82,0x00,0x00,0xac,0x83,0x00,0x00,
-0x27,0x82,0xb4,0x00,0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x24,0x05,0x00,0x01,
-0xaf,0xa5,0x00,0x1c,0x90,0x62,0x00,0x16,0x00,0x13,0xa8,0xc0,0x32,0x51,0x00,0x02,
-0x34,0x42,0x00,0x04,0xa0,0x62,0x00,0x16,0x8f,0xa3,0x00,0x20,0x8f,0xa4,0x00,0x18,
-0x00,0x03,0x13,0x43,0x00,0x04,0x1a,0x02,0x30,0x47,0x00,0x01,0x12,0x20,0x00,0x04,
-0x30,0x64,0x07,0xff,0x2e,0x03,0x00,0x04,0x32,0x42,0x00,0x33,0x00,0x43,0x90,0x0b,
-0x8f,0xa5,0x00,0x24,0x8f,0xa6,0x00,0x1c,0x00,0x12,0x10,0x40,0x00,0x05,0x19,0xc0,
-0x00,0x47,0x10,0x21,0x00,0x06,0x2a,0x80,0x00,0x43,0x10,0x21,0x00,0x10,0x32,0x00,
-0x00,0x04,0x24,0x80,0x02,0x65,0x28,0x21,0x00,0xa4,0x28,0x21,0x00,0x46,0x10,0x21,
-0x00,0x17,0x1c,0x00,0x3c,0x04,0xc0,0x00,0x00,0x43,0x30,0x21,0x16,0x80,0x00,0x29,
-0x00,0xa4,0x28,0x21,0x3c,0x02,0xb0,0x05,0x34,0x42,0x04,0x00,0x3c,0x03,0xb0,0x05,
-0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x04,0x34,0x84,0x02,0x28,
-0x24,0x02,0x00,0x01,0xac,0x65,0x00,0x00,0xa0,0x82,0x00,0x00,0x3c,0x02,0xb0,0x09,
-0x34,0x42,0x01,0x46,0x90,0x44,0x00,0x00,0x91,0xe3,0x00,0x09,0x30,0x86,0x00,0x01,
-0x02,0x83,0x18,0x26,0x00,0x03,0x30,0x0b,0x14,0xc0,0x00,0x03,0x00,0x00,0x28,0x21,
-0x13,0xc0,0x00,0x03,0x02,0xb3,0x10,0x21,0x24,0x05,0x00,0x01,0x02,0xb3,0x10,0x21,
-0x27,0x83,0x90,0x08,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x84,0x48,0x00,0x04,
-0x00,0xa0,0x30,0x21,0x00,0xe0,0x20,0x21,0x02,0x80,0x28,0x21,0x02,0xc0,0x38,0x21,
-0x0c,0x00,0x00,0x70,0xaf,0xa8,0x00,0x10,0x7b,0xbe,0x02,0xbc,0x7b,0xb6,0x02,0x7c,
-0x7b,0xb4,0x02,0x3c,0x7b,0xb2,0x01,0xfc,0x7b,0xb0,0x01,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x58,0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x3d,0x3c,0x02,0xb0,0x05,
-0x24,0x02,0x00,0x02,0x12,0x82,0x00,0x31,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x03,
-0x12,0x82,0x00,0x25,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10,0x12,0x82,0x00,0x19,
-0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x11,0x12,0x82,0x00,0x0d,0x3c,0x02,0xb0,0x05,
-0x24,0x02,0x00,0x12,0x16,0x82,0xff,0xd1,0x3c,0x02,0xb0,0x05,0x3c,0x03,0xb0,0x05,
-0x34,0x42,0x04,0x20,0x3c,0x04,0xb0,0x05,0x34,0x63,0x04,0x24,0xac,0x46,0x00,0x00,
-0x34,0x84,0x02,0x28,0xac,0x65,0x00,0x00,0x08,0x00,0x07,0xe6,0x24,0x02,0x00,0x20,
-0x34,0x42,0x04,0x40,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,
-0x34,0x63,0x04,0x44,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x40,0x08,0x00,0x07,0xe6,
-0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x28,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,
-0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x2c,0x34,0x84,0x02,0x28,0x24,0x02,0xff,0x80,
-0x08,0x00,0x07,0xe6,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x18,0x3c,0x03,0xb0,0x05,
-0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x1c,0x34,0x84,0x02,0x28,
-0x24,0x02,0x00,0x08,0x08,0x00,0x07,0xe6,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x10,
-0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x14,
-0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x04,0x08,0x00,0x07,0xe6,0xac,0x65,0x00,0x00,
-0x34,0x42,0x04,0x08,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,
-0x34,0x63,0x04,0x0c,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x02,0x08,0x00,0x07,0xe6,
-0xac,0x65,0x00,0x00,0x24,0x17,0x00,0x14,0x08,0x00,0x07,0xb8,0x24,0x13,0x01,0x02,
-0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x0c,0x00,0x90,0x18,0x2b,0x10,0x60,0x00,0x0c,
-0x26,0x02,0x00,0x04,0x27,0x85,0xbb,0x1c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21,
-0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b,
-0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x2e,0x06,0x00,0x0c,0x26,0x02,0x00,0x04,
-0x08,0x00,0x07,0xa2,0x00,0x46,0x80,0x0a,0x27,0x82,0xb4,0x00,0x01,0x82,0x20,0x21,
-0x8c,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0xe2,0x00,0x19,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x27,0x82,0x90,0x20,0x00,0xc2,0x10,0x21,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x14,0x00,0x00,0x00,0x00,
-0x90,0xe3,0x00,0x16,0x27,0x82,0x90,0x08,0x00,0xc2,0x10,0x21,0x34,0x63,0x00,0x20,
-0x90,0x50,0x00,0x07,0xa0,0xe3,0x00,0x16,0x8c,0x84,0x00,0x00,0x00,0x0a,0x1e,0x42,
-0x24,0x06,0x00,0x01,0x90,0x82,0x00,0x16,0x30,0x71,0x00,0x02,0x30,0x72,0x00,0x3f,
-0x30,0x42,0x00,0xfb,0x24,0x17,0x00,0x18,0x24,0x13,0x01,0x03,0x24,0x15,0x08,0x18,
-0xaf,0xa6,0x00,0x1c,0x08,0x00,0x07,0xc2,0xa0,0x82,0x00,0x16,0x8d,0x02,0x00,0x04,
-0x00,0x0a,0x1c,0x42,0x30,0x42,0x00,0x10,0x14,0x40,0x00,0x15,0x30,0x72,0x00,0x3f,
-0x81,0x22,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x11,0x30,0x72,0x00,0x3e,
-0x27,0x83,0x90,0x18,0x00,0xc3,0x18,0x21,0x80,0x64,0x00,0x00,0x27,0x83,0xb5,0x78,
-0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x05,0x90,0x43,0x00,0x04,
-0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x24,0x30,0x63,0x00,0x01,0x02,0x43,0x90,0x25,
-0x27,0x85,0xb4,0x00,0x01,0x85,0x28,0x21,0x8c,0xa6,0x00,0x00,0x01,0x73,0x10,0x21,
-0x27,0x83,0x90,0x10,0x90,0xc4,0x00,0x16,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,
-0x30,0x84,0x00,0xdf,0x90,0x50,0x00,0x00,0xa0,0xc4,0x00,0x16,0x80,0xc6,0x00,0x12,
-0x8c,0xa3,0x00,0x00,0x2d,0xc4,0x00,0x02,0xaf,0xa6,0x00,0x1c,0x90,0x62,0x00,0x16,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfb,0x14,0x80,0x00,0x06,0xa0,0x62,0x00,0x16,
-0x24,0x02,0x00,0x06,0x11,0xc2,0x00,0x03,0x24,0x02,0x00,0x04,0x15,0xc2,0xff,0x0e,
-0x32,0x51,0x00,0x02,0x32,0x51,0x00,0x02,0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x0f,
-0x00,0x11,0x18,0x2b,0x32,0x02,0x00,0x0f,0x34,0x42,0x00,0x10,0x00,0x03,0x19,0x00,
-0x00,0x43,0x18,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xe0,0xa0,0x43,0x00,0x00,
-0x00,0x00,0x20,0x21,0x02,0x00,0x28,0x21,0x0c,0x00,0x02,0x03,0xaf,0xaf,0x00,0x28,
-0x8f,0xaf,0x00,0x28,0x08,0x00,0x07,0xc2,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0xbd,
-0x32,0x03,0x00,0xff,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x42,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0x14,0x40,0xfe,0xaa,0x00,0x00,0x00,0x00,
-0x91,0xe2,0x00,0x09,0x00,0x00,0x00,0x00,0x02,0x82,0x10,0x26,0x08,0x00,0x07,0x79,
-0x00,0x02,0x28,0x0b,0x08,0x00,0x07,0x7f,0x00,0x00,0xb0,0x21,0x24,0x02,0x00,0x10,
-0x10,0xc2,0x00,0x08,0x24,0x02,0x00,0x11,0x10,0xc2,0xfe,0x7d,0x00,0x07,0x17,0x83,
-0x24,0x02,0x00,0x12,0x14,0xc2,0xfe,0x7b,0x00,0x07,0x17,0x43,0x08,0x00,0x07,0x59,
-0x30,0x5e,0x00,0x01,0x08,0x00,0x07,0x59,0x00,0x07,0xf7,0xc2,0x00,0x04,0x10,0x40,
-0x27,0x83,0x80,0x1c,0x00,0x43,0x10,0x21,0x00,0x80,0x40,0x21,0x94,0x44,0x00,0x00,
-0x2d,0x07,0x00,0x04,0x24,0xc2,0x00,0x03,0x00,0x47,0x30,0x0a,0x00,0x86,0x00,0x18,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x23,0x8c,
-0xac,0x62,0x00,0x00,0x2d,0x06,0x00,0x10,0x00,0x00,0x20,0x12,0x00,0x04,0x22,0x42,
-0x24,0x84,0x00,0x01,0x24,0x83,0x00,0xc0,0x10,0xe0,0x00,0x0b,0x24,0x82,0x00,0x60,
-0x00,0x40,0x20,0x21,0x00,0x65,0x20,0x0a,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x00,0x44,0x20,0x04,
-0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x24,0x85,0x00,0x28,0x24,0x83,0x00,0x24,
-0x31,0x02,0x00,0x08,0x14,0xc0,0xff,0xf4,0x24,0x84,0x00,0x14,0x00,0x60,0x20,0x21,
-0x08,0x00,0x08,0xfa,0x00,0xa2,0x20,0x0b,0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0xaf,0xb0,0x00,0x10,0x24,0x42,0x24,0x28,0x00,0x80,0x80,0x21,
-0x34,0x63,0x00,0x20,0x3c,0x04,0xb0,0x03,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,
-0xaf,0xbf,0x00,0x1c,0x83,0xb1,0x00,0x33,0x83,0xa8,0x00,0x37,0x34,0x84,0x01,0x10,
-0xac,0x62,0x00,0x00,0x2e,0x02,0x00,0x10,0x00,0xe0,0x90,0x21,0x8c,0x87,0x00,0x00,
-0x14,0x40,0x00,0x0c,0x2e,0x02,0x00,0x0c,0x3c,0x02,0x00,0x0f,0x34,0x42,0xf0,0x00,
-0x00,0xe2,0x10,0x24,0x14,0x40,0x00,0x37,0x32,0x02,0x00,0x08,0x32,0x02,0x00,0x07,
-0x27,0x83,0x80,0xcc,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,
-0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x03,0x02,0x00,0x20,0x21,0x32,0x02,0x00,0x0f,
-0x24,0x44,0x00,0x0c,0x00,0x87,0x10,0x06,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x07,
-0x2c,0x82,0x00,0x0c,0x00,0x04,0x10,0x80,0x27,0x83,0xb4,0x50,0x00,0x43,0x10,0x21,
-0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x82,0x00,0x0c,0x14,0x40,0x00,0x05,
-0x00,0x05,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x82,0x10,0x21,
-0x24,0x44,0x00,0x04,0x15,0x00,0x00,0x02,0x24,0x06,0x00,0x20,0x24,0x06,0x00,0x0e,
-0x0c,0x00,0x08,0xe3,0x00,0x00,0x00,0x00,0x00,0x40,0x30,0x21,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x01,0x00,0x90,0x43,0x00,0x00,0x2e,0x04,0x00,0x04,0x24,0x02,0x00,0x10,
-0x24,0x05,0x00,0x0a,0x00,0x44,0x28,0x0a,0x30,0x63,0x00,0x01,0x14,0x60,0x00,0x02,
-0x00,0x05,0x10,0x40,0x00,0xa0,0x10,0x21,0x30,0x45,0x00,0xff,0x00,0xc5,0x10,0x21,
-0x24,0x46,0x00,0x46,0x02,0x26,0x18,0x04,0xa6,0x43,0x00,0x00,0x8f,0xbf,0x00,0x1c,
-0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x00,0xc0,0x10,0x21,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x10,0x40,0xff,0xcf,0x2e,0x02,0x00,0x0c,0x32,0x02,0x00,0x07,
-0x27,0x83,0x80,0xc4,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,0x08,0x00,0x09,0x28,
-0x02,0x04,0x80,0x23,0x27,0xbd,0xff,0xb8,0x00,0x05,0x38,0x80,0x27,0x82,0xb4,0x00,
-0xaf,0xbe,0x00,0x40,0xaf,0xb6,0x00,0x38,0xaf,0xb3,0x00,0x2c,0xaf,0xbf,0x00,0x44,
-0xaf,0xb7,0x00,0x3c,0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xb2,0x00,0x28,
-0xaf,0xb1,0x00,0x24,0xaf,0xb0,0x00,0x20,0x00,0xe2,0x38,0x21,0x8c,0xe6,0x00,0x00,
-0xaf,0xa5,0x00,0x4c,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20,
-0x24,0x42,0x25,0x84,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00,0xa0,0xc3,0x00,0x12,
-0x8c,0xe5,0x00,0x00,0x94,0xc3,0x00,0x06,0x90,0xa2,0x00,0x16,0xa4,0xc3,0x00,0x14,
-0x27,0x83,0x90,0x00,0x34,0x42,0x00,0x08,0xa0,0xa2,0x00,0x16,0x8c,0xe8,0x00,0x00,
-0xaf,0xa4,0x00,0x48,0x27,0x82,0x90,0x04,0x95,0x11,0x00,0x14,0x00,0x00,0x00,0x00,
-0x00,0x11,0x98,0xc0,0x02,0x71,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x82,0x10,0x21,
-0x8c,0x52,0x00,0x18,0x00,0x83,0x18,0x21,0x84,0x75,0x00,0x06,0x8e,0x45,0x00,0x08,
-0x8e,0x46,0x00,0x04,0x8e,0x47,0x00,0x04,0x00,0x05,0x1c,0x82,0x00,0x06,0x31,0x42,
-0x27,0x82,0x90,0x10,0x30,0x63,0x00,0x01,0x30,0xc6,0x00,0x01,0x00,0x82,0x20,0x21,
-0xa5,0x15,0x00,0x1a,0x00,0x05,0x14,0x42,0xaf,0xa3,0x00,0x18,0xaf,0xa6,0x00,0x1c,
-0x30,0xe7,0x00,0x10,0x30,0x56,0x00,0x01,0x80,0x97,0x00,0x06,0x14,0xe0,0x00,0x47,
-0x00,0x05,0xf7,0xc2,0x80,0x82,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x44,
-0x02,0x71,0x10,0x21,0x93,0x90,0xbb,0xe9,0x00,0x00,0x00,0x00,0x2e,0x02,0x00,0x0c,
-0x14,0x40,0x00,0x06,0x02,0x00,0x20,0x21,0x00,0x16,0x10,0x40,0x00,0x43,0x10,0x21,
-0x00,0x02,0x11,0x00,0x02,0x02,0x10,0x21,0x24,0x44,0x00,0x04,0x02,0x71,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0x00,0x80,0x80,0x21,
-0xa0,0x44,0x00,0x03,0xa0,0x44,0x00,0x00,0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21,
-0x0c,0x00,0x08,0xe3,0x02,0xa0,0x30,0x21,0x02,0x71,0x18,0x21,0x00,0x03,0x88,0x80,
-0x00,0x40,0xa0,0x21,0x27,0x82,0x90,0x20,0x02,0x22,0x10,0x21,0x8c,0x44,0x00,0x00,
-0x26,0xe3,0x00,0x02,0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21,0x00,0x04,0x25,0xc2,
-0x00,0x03,0x18,0x43,0x30,0x84,0x00,0x01,0x00,0x03,0x18,0x40,0x03,0xc4,0x20,0x24,
-0x14,0x80,0x00,0x15,0x02,0x43,0x38,0x21,0x3c,0x08,0xb0,0x03,0x35,0x08,0x00,0x28,
-0x8d,0x03,0x00,0x00,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x48,0x27,0x82,0x90,0x08,
-0x02,0x22,0x10,0x21,0x24,0x63,0x00,0x01,0x02,0xa0,0x28,0x21,0xa4,0x54,0x00,0x04,
-0x00,0xc0,0x38,0x21,0x0c,0x00,0x07,0x2f,0xad,0x03,0x00,0x00,0x7b,0xbe,0x02,0x3c,
-0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48,0x8f,0xa2,0x00,0x1c,0x8f,0xa6,0x00,0x18,
-0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0x0a,
-0xaf,0xa0,0x00,0x14,0x08,0x00,0x09,0xc6,0x02,0x82,0xa0,0x21,0x02,0x71,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00,
-0x08,0x00,0x09,0xb2,0xa0,0x50,0x00,0x03,0x27,0xbd,0xff,0xb8,0xaf,0xb1,0x00,0x24,
-0x8f,0xb1,0x00,0x5c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,
-0x24,0x42,0x27,0xa8,0xaf,0xbe,0x00,0x40,0xaf,0xb7,0x00,0x3c,0xaf,0xb6,0x00,0x38,
-0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xa5,0x00,0x4c,0x8f,0xb5,0x00,0x58,
-0xaf,0xbf,0x00,0x44,0xaf,0xb3,0x00,0x2c,0xaf,0xb2,0x00,0x28,0xaf,0xb0,0x00,0x20,
-0x00,0xe0,0xb0,0x21,0xac,0x62,0x00,0x00,0x00,0x80,0xf0,0x21,0x00,0x00,0xb8,0x21,
-0x16,0x20,0x00,0x2b,0x00,0x00,0xa0,0x21,0x27,0x85,0xb4,0x00,0x00,0x07,0x10,0x80,
-0x00,0x45,0x10,0x21,0x8c,0x53,0x00,0x00,0x00,0x15,0x18,0x80,0x00,0x65,0x18,0x21,
-0x92,0x62,0x00,0x16,0x8c,0x72,0x00,0x00,0x30,0x42,0x00,0x03,0x14,0x40,0x00,0x2d,
-0x00,0x00,0x00,0x00,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x03,
-0x14,0x40,0x00,0x28,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x18,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x38,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x14,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x3c,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x0f,0x3c,0x03,0xb0,0x09,0x3c,0x05,0xb0,0x05,0x34,0x63,0x01,0x44,
-0x34,0xa5,0x02,0x52,0x94,0x66,0x00,0x00,0x90,0xa2,0x00,0x00,0x8f,0xa3,0x00,0x4c,
-0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x06,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x04,
-0x30,0xc6,0xff,0xff,0x2c,0xc2,0x00,0x41,0x10,0x40,0x00,0x09,0x24,0x05,0x00,0x14,
-0x02,0x20,0x10,0x21,0x7b,0xbe,0x02,0x3c,0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc,
-0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48,
-0x0c,0x00,0x07,0x0a,0x24,0x06,0x01,0x07,0x24,0x02,0x00,0x01,0x08,0x00,0x0a,0x2c,
-0xa3,0xc2,0x00,0x11,0x10,0xc0,0x00,0x1c,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x17,
-0x00,0xc0,0x88,0x21,0x96,0x54,0x00,0x1a,0x02,0xa0,0xb8,0x21,0x12,0x20,0xff,0xed,
-0x02,0x20,0x10,0x21,0x27,0x83,0xb4,0x00,0x00,0x17,0x10,0x80,0x00,0x43,0x10,0x21,
-0x8c,0x44,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x28,0x80,0x86,0x00,0x12,
-0x8c,0x62,0x00,0x00,0x00,0x14,0x2c,0x00,0x00,0x05,0x2c,0x03,0x00,0x46,0x10,0x21,
-0x8f,0xa6,0x00,0x4c,0x02,0xe0,0x38,0x21,0x03,0xc0,0x20,0x21,0x0c,0x00,0x07,0x2f,
-0xac,0x62,0x00,0x00,0x08,0x00,0x0a,0x2c,0xaf,0xd1,0x00,0x40,0x96,0x74,0x00,0x1a,
-0x08,0x00,0x0a,0x3f,0x02,0xc0,0xb8,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,
-0x8c,0x50,0x00,0x00,0x02,0x60,0x20,0x21,0x0c,0x00,0x1e,0xf3,0x02,0x00,0x28,0x21,
-0x30,0x42,0x00,0xff,0x02,0x00,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x1e,0xf3,
-0xaf,0xa2,0x00,0x18,0x8f,0xa4,0x00,0x18,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0xed,
-0x30,0x50,0x00,0xff,0x12,0x00,0x00,0x18,0x24,0x11,0x00,0x01,0x96,0x63,0x00,0x14,
-0x96,0x44,0x00,0x14,0x27,0x85,0x90,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x00,0x04,0x18,0xc0,0x8c,0x46,0x00,0x08,
-0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x00,0x06,0x17,0x02,
-0x24,0x04,0x00,0xff,0x8c,0x63,0x00,0x08,0x10,0x44,0x00,0xd6,0x00,0x03,0x17,0x02,
-0x10,0x44,0x00,0xd5,0x3c,0x02,0x80,0x00,0x00,0x66,0x18,0x2b,0x24,0x11,0x00,0x02,
-0x24,0x02,0x00,0x01,0x00,0x43,0x88,0x0a,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x5a,
-0x24,0x02,0x00,0x02,0x16,0x22,0xff,0xbd,0x00,0x00,0x00,0x00,0x96,0x49,0x00,0x14,
-0x27,0x82,0x90,0x04,0x02,0xa0,0xb8,0x21,0x00,0x09,0x50,0xc0,0x01,0x49,0x18,0x21,
-0x00,0x03,0x40,0x80,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18,0x00,0x00,0x00,0x00,
-0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04,0x00,0x05,0x24,0x42,
-0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01,0x14,0x40,0x00,0x41,
-0x30,0x87,0x00,0x01,0x27,0x82,0x90,0x18,0x01,0x02,0x10,0x21,0x80,0x44,0x00,0x00,
-0x27,0x82,0xb5,0x78,0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,
-0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05,
-0x27,0x84,0xb4,0xa0,0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2b,
-0x2c,0x64,0x00,0x0c,0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00,
-0x00,0x62,0x10,0x21,0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xe1,
-0x14,0x80,0x00,0x06,0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21,
-0x00,0x02,0x11,0x00,0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21,
-0x27,0x83,0x90,0x10,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21,
-0xa0,0x45,0x00,0x03,0xa0,0x45,0x00,0x00,0x24,0x02,0x00,0x08,0x12,0x02,0x00,0x0b,
-0x24,0x02,0x00,0x01,0x00,0x60,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x6f,
-0xaf,0xa2,0x00,0x10,0x30,0x54,0xff,0xff,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00,
-0x02,0x02,0x10,0x25,0x08,0x00,0x0a,0x3f,0xa2,0x42,0x00,0x16,0x00,0x60,0x28,0x21,
-0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x20,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0a,0xc2,
-0x30,0x54,0xff,0xff,0x08,0x00,0x0a,0xaa,0x00,0x60,0x10,0x21,0x14,0x80,0xff,0xfd,
-0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x08,0x00,0x0a,0xaa,
-0x24,0x42,0x00,0x04,0x27,0x82,0x90,0x10,0x01,0x02,0x10,0x21,0x90,0x43,0x00,0x00,
-0x08,0x00,0x0a,0xba,0xa0,0x43,0x00,0x03,0x96,0x69,0x00,0x14,0x02,0xc0,0xb8,0x21,
-0x24,0x0b,0x00,0x01,0x00,0x09,0x10,0xc0,0x00,0x49,0x18,0x21,0x00,0x03,0x40,0x80,
-0x00,0x40,0x50,0x21,0x27,0x82,0x90,0x04,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18,
-0x00,0x00,0x00,0x00,0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04,
-0x00,0x05,0x24,0x42,0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01,
-0x10,0x40,0x00,0x0d,0x30,0x87,0x00,0x01,0x27,0x82,0x90,0x18,0x01,0x02,0x10,0x21,
-0x80,0x43,0x00,0x00,0x00,0x00,0x58,0x21,0x00,0x03,0x11,0x00,0x00,0x43,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x23,0x00,0x02,0x10,0x80,0x27,0x83,0xb5,0x70,
-0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x04,0x11,0x60,0x00,0x4f,0x00,0x00,0x00,0x00,
-0x01,0x49,0x10,0x21,0x00,0x02,0x20,0x80,0x27,0x85,0x90,0x10,0x00,0x85,0x10,0x21,
-0x80,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x42,0x01,0x49,0x10,0x21,
-0x27,0x82,0x90,0x18,0x00,0x82,0x10,0x21,0x80,0x44,0x00,0x00,0x27,0x82,0xb5,0x78,
-0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x23,
-0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05,0x27,0x84,0xb4,0xa0,
-0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2c,0x2c,0x64,0x00,0x0c,
-0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,
-0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xe1,0x14,0x80,0x00,0x06,
-0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,
-0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21,0x27,0x83,0x90,0x10,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21,0xa0,0x45,0x00,0x03,
-0xa0,0x45,0x00,0x00,0x8f,0xa4,0x00,0x18,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x0c,
-0x00,0x60,0x28,0x21,0x24,0x02,0x00,0x01,0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x6f,
-0xaf,0xa2,0x00,0x10,0x8f,0xa3,0x00,0x18,0x30,0x54,0xff,0xff,0x92,0x62,0x00,0x16,
-0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x25,0x08,0x00,0x0a,0x3f,0xa2,0x62,0x00,0x16,
-0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x20,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0b,0x31,
-0x00,0x00,0x00,0x00,0x08,0x00,0x0b,0x19,0x00,0x60,0x10,0x21,0x14,0x80,0xff,0xfd,
-0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x08,0x00,0x0b,0x19,
-0x24,0x42,0x00,0x04,0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x90,0x43,0x00,0x00,
-0x08,0x00,0x0b,0x29,0xa0,0x43,0x00,0x03,0x27,0x85,0x90,0x10,0x08,0x00,0x0b,0x45,
-0x01,0x49,0x10,0x21,0x3c,0x02,0x80,0x00,0x00,0x62,0x18,0x26,0x08,0x00,0x0a,0x7a,
-0x00,0xc2,0x30,0x26,0x12,0x00,0xff,0x2d,0x24,0x02,0x00,0x01,0x08,0x00,0x0a,0x7f,
-0x24,0x11,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0,
-0x24,0x42,0x2d,0x54,0x34,0x63,0x00,0x20,0x3c,0x05,0xb0,0x05,0xaf,0xb3,0x00,0x24,
-0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x28,0xaf,0xb0,0x00,0x18,
-0xac,0x62,0x00,0x00,0x34,0xa5,0x02,0x42,0x90,0xa2,0x00,0x00,0x00,0x80,0x90,0x21,
-0x24,0x11,0x00,0x10,0x30,0x53,0x00,0xff,0x24,0x02,0x00,0x10,0x12,0x22,0x00,0xcf,
-0x00,0x00,0x18,0x21,0x24,0x02,0x00,0x11,0x12,0x22,0x00,0xc1,0x24,0x02,0x00,0x12,
-0x12,0x22,0x00,0xb4,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0xad,0xae,0x43,0x00,0x40,
-0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x44,0x00,0x00,0x3c,0x03,0x00,0x02,
-0x34,0x63,0x00,0xff,0x00,0x83,0x80,0x24,0x00,0x10,0x14,0x43,0x10,0x40,0x00,0x05,
-0x00,0x00,0x00,0x00,0x8e,0x42,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x92,
-0x00,0x00,0x00,0x00,0x93,0x83,0x8b,0x71,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02,
-0x10,0x40,0x00,0x04,0x32,0x10,0x00,0xff,0x00,0x10,0x11,0xc3,0x14,0x40,0x00,0x86,
-0x00,0x00,0x00,0x00,0x16,0x00,0x00,0x15,0x02,0x00,0x10,0x21,0x26,0x22,0x00,0x01,
-0x30,0x51,0x00,0xff,0x2e,0x23,0x00,0x13,0x14,0x60,0xff,0xdb,0x24,0x03,0x00,0x02,
-0x12,0x63,0x00,0x73,0x24,0x02,0x00,0x05,0x2a,0x62,0x00,0x03,0x10,0x40,0x00,0x58,
-0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x62,0x00,0x4b,0x02,0x40,0x20,0x21,
-0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x70,0x00,0xff,0x12,0x00,0x00,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x28,
-0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,
-0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24,0x24,0x02,0x00,0x07,0x02,0x40,0x20,0x21,
-0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea,
-0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x24,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,
-0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xec,0x02,0x00,0x10,0x21,
-0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x24,0x02,0x00,0x05,0x02,0x40,0x20,0x21,
-0x24,0x05,0x00,0x01,0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea,
-0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x28,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,
-0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xdc,0x02,0x00,0x10,0x21,
-0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c,0x24,0x02,0x00,0x03,0x02,0x40,0x20,0x21,
-0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea,
-0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x2c,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,
-0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xcc,0x02,0x00,0x10,0x21,
-0x92,0x46,0x00,0x07,0x8e,0x43,0x00,0x30,0x24,0x02,0x00,0x02,0x02,0x40,0x20,0x21,
-0x24,0x05,0x00,0x03,0x24,0x07,0x00,0x01,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea,
-0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x30,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,
-0x08,0x00,0x0b,0x9b,0x30,0x42,0x00,0xff,0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24,
-0x24,0x02,0x00,0x07,0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10,
-0x0c,0x00,0x09,0xea,0xaf,0xa3,0x00,0x14,0x08,0x00,0x0b,0x94,0xae,0x42,0x00,0x24,
-0x12,0x62,0x00,0x0d,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x08,0x16,0x62,0xff,0xa8,
-0x02,0x40,0x20,0x21,0x92,0x46,0x00,0x07,0x8e,0x42,0x00,0x30,0x24,0x05,0x00,0x03,
-0x24,0x07,0x00,0x01,0xaf,0xa3,0x00,0x10,0x0c,0x00,0x09,0xea,0xaf,0xa2,0x00,0x14,
-0x08,0x00,0x0b,0x94,0xae,0x42,0x00,0x30,0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c,
-0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10,
-0x0c,0x00,0x09,0xea,0xaf,0xa3,0x00,0x14,0x08,0x00,0x0b,0x94,0xae,0x42,0x00,0x2c,
-0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x01,
-0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea,0xaf,0xa3,0x00,0x14,
-0x08,0x00,0x0b,0x94,0xae,0x42,0x00,0x28,0x0c,0x00,0x01,0x57,0x24,0x04,0x00,0x01,
-0x08,0x00,0x0b,0x85,0x00,0x00,0x00,0x00,0x8f,0x84,0xb4,0x40,0xae,0x40,0x00,0x34,
-0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x66,0x00,0x00,0x00,0x00,0x93,0x83,0x8b,0x71,
-0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02,0x10,0x40,0xff,0x69,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x01,0x57,0x00,0x00,0x20,0x21,0x08,0x00,0x0b,0x7d,0x00,0x00,0x00,0x00,
-0x02,0x40,0x20,0x21,0x0c,0x00,0x09,0x61,0x02,0x20,0x28,0x21,0x08,0x00,0x0b,0x71,
-0x3c,0x02,0xb0,0x05,0x8e,0x42,0x00,0x3c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x4a,
-0x00,0x00,0x00,0x00,0x8f,0x82,0xb4,0x48,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,0x08,0x00,0x0b,0x6e,0xae,0x43,0x00,0x3c,
-0x8e,0x42,0x00,0x38,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x3d,0x24,0x02,0x00,0x12,
-0x8f,0x82,0xb4,0x44,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00,
-0x00,0x02,0x18,0x2b,0x08,0x00,0x0b,0x6e,0xae,0x43,0x00,0x38,0x8e,0x42,0x00,0x34,
-0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x30,0x24,0x02,0x00,0x11,0x8f,0x82,0xb4,0x40,
-0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,
-0x08,0x00,0x0b,0x6e,0xae,0x43,0x00,0x34,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x27,0xbd,0xff,0xe0,0x34,0x63,0x00,0x20,0x24,0x42,0x31,0x08,0x3c,0x08,0xb0,0x03,
-0xaf,0xb1,0x00,0x14,0xac,0x62,0x00,0x00,0x35,0x08,0x01,0x00,0xaf,0xbf,0x00,0x18,
-0xaf,0xb0,0x00,0x10,0x91,0x03,0x00,0x00,0x00,0xa0,0x48,0x21,0x24,0x11,0x00,0x0a,
-0x2c,0xa5,0x00,0x04,0x24,0x02,0x00,0x10,0x00,0x45,0x88,0x0a,0x30,0x63,0x00,0x01,
-0x00,0xc0,0x28,0x21,0x14,0x60,0x00,0x02,0x00,0x11,0x40,0x40,0x02,0x20,0x40,0x21,
-0x84,0x83,0x00,0x0c,0x31,0x11,0x00,0xff,0x01,0x20,0x20,0x21,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x08,0x00,0x43,0x10,0x21,
-0x84,0x43,0x00,0x04,0x24,0x06,0x00,0x0e,0x10,0xe0,0x00,0x06,0x02,0x23,0x80,0x21,
-0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x0c,0x00,0x08,0xe3,0x00,0x00,0x00,0x00,0x02,0x11,0x18,0x21,
-0x08,0x00,0x0c,0x64,0x00,0x62,0x80,0x21,0x27,0xbd,0xff,0xd0,0xaf,0xbf,0x00,0x28,
-0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb5,0x00,0x24,
-0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x84,0x82,0x00,0x0c,0x3c,0x06,0xb0,0x03,
-0x34,0xc6,0x00,0x20,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,
-0x27,0x82,0x90,0x04,0x00,0x62,0x10,0x21,0x8c,0x55,0x00,0x18,0x3c,0x02,0x80,0x00,
-0x24,0x42,0x31,0xb8,0xac,0xc2,0x00,0x00,0x8e,0xb0,0x00,0x08,0x27,0x82,0x90,0x08,
-0x00,0x62,0x18,0x21,0x90,0x71,0x00,0x07,0x00,0x10,0x86,0x43,0x32,0x10,0x00,0x01,
-0x00,0xa0,0x38,0x21,0x02,0x00,0x30,0x21,0x00,0xa0,0x98,0x21,0x02,0x20,0x28,0x21,
-0x0c,0x00,0x0c,0x42,0x00,0x80,0x90,0x21,0x02,0x20,0x20,0x21,0x02,0x00,0x28,0x21,
-0x24,0x06,0x00,0x14,0x0c,0x00,0x08,0xe3,0x00,0x40,0xa0,0x21,0x86,0x43,0x00,0x0c,
-0x3c,0x09,0xb0,0x09,0x3c,0x08,0xb0,0x09,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0x80,0x43,0x00,0x06,
-0x3c,0x07,0xb0,0x09,0x3c,0x05,0xb0,0x09,0x28,0x62,0x00,0x00,0x24,0x64,0x00,0x03,
-0x00,0x82,0x18,0x0b,0x00,0x03,0x18,0x83,0x3c,0x02,0xb0,0x09,0x00,0x03,0x18,0x80,
-0x34,0x42,0x01,0x02,0x35,0x29,0x01,0x10,0x35,0x08,0x01,0x14,0x34,0xe7,0x01,0x20,
-0x34,0xa5,0x01,0x24,0xa4,0x54,0x00,0x00,0x12,0x60,0x00,0x11,0x02,0xa3,0xa8,0x21,
-0x8e,0xa2,0x00,0x0c,0x8e,0xa3,0x00,0x08,0x00,0x02,0x14,0x00,0x00,0x03,0x1c,0x02,
-0x00,0x43,0x10,0x21,0xad,0x22,0x00,0x00,0x8e,0xa3,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x00,0x03,0x1c,0x02,0xa5,0x03,0x00,0x00,0x8f,0xbf,0x00,0x28,0x7b,0xb4,0x01,0x3c,
-0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,
-0x8e,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0xad,0x22,0x00,0x00,0x8e,0xa4,0x00,0x08,
-0x00,0x00,0x00,0x00,0xa5,0x04,0x00,0x00,0x7a,0xa2,0x00,0x7c,0x00,0x00,0x00,0x00,
-0x00,0x03,0x1c,0x00,0x00,0x02,0x14,0x02,0x00,0x62,0x18,0x21,0xac,0xe3,0x00,0x00,
-0x8e,0xa2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x02,0x08,0x00,0x0c,0xb6,
-0xa4,0xa2,0x00,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10,
-0xaf,0xbf,0x00,0x1c,0xaf,0xb1,0x00,0x14,0x84,0x82,0x00,0x0c,0x00,0x80,0x90,0x21,
-0x3c,0x05,0xb0,0x03,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,
-0x27,0x82,0x90,0x04,0x00,0x82,0x10,0x21,0x8c,0x51,0x00,0x18,0x3c,0x02,0x80,0x00,
-0x34,0xa5,0x00,0x20,0x24,0x42,0x33,0x34,0x27,0x83,0x90,0x08,0xac,0xa2,0x00,0x00,
-0x00,0x83,0x20,0x21,0x3c,0x02,0xb0,0x03,0x90,0x86,0x00,0x07,0x34,0x42,0x01,0x00,
-0x8e,0x23,0x00,0x08,0x90,0x44,0x00,0x00,0x2c,0xc5,0x00,0x04,0x24,0x02,0x00,0x10,
-0x24,0x10,0x00,0x0a,0x00,0x45,0x80,0x0a,0x00,0x03,0x1e,0x43,0x30,0x84,0x00,0x01,
-0x30,0x65,0x00,0x01,0x14,0x80,0x00,0x02,0x00,0x10,0x10,0x40,0x02,0x00,0x10,0x21,
-0x00,0xc0,0x20,0x21,0x24,0x06,0x00,0x20,0x0c,0x00,0x08,0xe3,0x30,0x50,0x00,0xff,
-0x86,0x44,0x00,0x0c,0x27,0x85,0x90,0x10,0x3c,0x06,0xb0,0x09,0x00,0x04,0x18,0xc0,
-0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x80,0x64,0x00,0x06,
-0x00,0x50,0x10,0x21,0x34,0xc6,0x01,0x02,0x24,0x85,0x00,0x03,0x28,0x83,0x00,0x00,
-0x00,0xa3,0x20,0x0b,0x00,0x04,0x20,0x83,0x00,0x04,0x20,0x80,0xa4,0xc2,0x00,0x00,
-0x02,0x24,0x20,0x21,0x8c,0x83,0x00,0x04,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x10,
-0xac,0x43,0x00,0x00,0x8c,0x86,0x00,0x08,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x14,
-0xa4,0x46,0x00,0x00,0x8c,0x85,0x00,0x0c,0x8c,0x82,0x00,0x08,0x3c,0x06,0xb0,0x09,
-0x00,0x05,0x2c,0x00,0x00,0x02,0x14,0x02,0x00,0xa2,0x28,0x21,0x34,0xc6,0x01,0x20,
-0xac,0xc5,0x00,0x00,0x8c,0x83,0x00,0x0c,0x3c,0x05,0xb0,0x09,0x34,0xa5,0x01,0x24,
-0x00,0x03,0x1c,0x02,0xa4,0xa3,0x00,0x00,0x92,0x42,0x00,0x0a,0x3c,0x03,0xb0,0x09,
-0x34,0x63,0x01,0x30,0x00,0x02,0x13,0x00,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff,
-0xa4,0x62,0x00,0x00,0x86,0x44,0x00,0x0c,0x27,0x83,0x90,0x18,0x8f,0xbf,0x00,0x1c,
-0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,
-0x94,0x44,0x00,0x02,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x3c,0x05,0xb0,0x09,
-0x34,0xa5,0x01,0x32,0xa4,0xa4,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
-0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0xaf,0xb0,0x00,0x10,
-0x34,0x42,0x00,0x20,0x00,0xa0,0x80,0x21,0x24,0x63,0x34,0xc0,0x00,0x05,0x2c,0x43,
-0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00,0x10,0xa0,0x00,0x05,
-0x00,0x80,0x88,0x21,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0xb6,
-0x00,0x00,0x00,0x00,0x32,0x10,0x00,0xff,0x12,0x00,0x00,0x4c,0x00,0x00,0x10,0x21,
-0x24,0x02,0x00,0x08,0x12,0x02,0x00,0xa3,0x2a,0x02,0x00,0x09,0x10,0x40,0x00,0x89,
-0x24,0x02,0x00,0x40,0x24,0x04,0x00,0x02,0x12,0x04,0x00,0x79,0x2a,0x02,0x00,0x03,
-0x10,0x40,0x00,0x69,0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x02,0x00,0x5a,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x00,0x08,0x3c,0x03,0x80,0x00,
-0xa2,0x20,0x00,0x4e,0xac,0x43,0x00,0x00,0x82,0x24,0x00,0x11,0x92,0x27,0x00,0x11,
-0x10,0x80,0x00,0x4e,0x00,0x00,0x00,0x00,0x92,0x26,0x00,0x0a,0x24,0x02,0x00,0x12,
-0x10,0x46,0x00,0x09,0x30,0xc2,0x00,0xff,0x27,0x83,0xb4,0x00,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x83,0x00,0x14,
-0x00,0x00,0x00,0x00,0xa6,0x23,0x00,0x0c,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x40,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x03,0xa2,0x23,0x00,0x10,
-0x14,0x60,0x00,0x2b,0x30,0x65,0x00,0x01,0x30,0xc2,0x00,0xff,0x27,0x83,0xb4,0x00,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x82,0x23,0x00,0x12,
-0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x30,0x42,0x00,0x01,
-0x00,0x62,0x18,0x21,0x00,0x03,0x26,0x00,0x14,0x80,0x00,0x18,0xa2,0x23,0x00,0x12,
-0x00,0x07,0x16,0x00,0x14,0x40,0x00,0x11,0x24,0x02,0x00,0x01,0x96,0x23,0x00,0x0c,
-0x27,0x84,0x90,0x10,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,0x3c,0x02,0xb0,0x00,
-0x00,0x65,0x18,0x21,0x00,0x62,0x18,0x21,0x90,0x64,0x00,0x00,0x90,0x62,0x00,0x04,
-0xa2,0x20,0x00,0x15,0xa3,0x80,0x8b,0xd4,0x24,0x02,0x00,0x01,0x8f,0xbf,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x0c,0xcd,
-0x02,0x20,0x20,0x21,0x92,0x27,0x00,0x11,0x08,0x00,0x0d,0x7d,0x00,0x07,0x16,0x00,
-0x0c,0x00,0x0c,0x6e,0x02,0x20,0x20,0x21,0x86,0x23,0x00,0x0c,0x27,0x84,0x90,0x08,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x44,0x20,0x21,
-0x90,0x85,0x00,0x07,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0xa2,0x25,0x00,0x13,
-0x90,0x83,0x00,0x07,0x08,0x00,0x0d,0x95,0xa0,0x43,0x00,0x02,0x92,0x26,0x00,0x0a,
-0x08,0x00,0x0d,0x5e,0x30,0xc2,0x00,0xff,0x8e,0x22,0x00,0x24,0x00,0x00,0x00,0x00,
-0x10,0x50,0x00,0x07,0xa2,0x20,0x00,0x08,0x24,0x02,0x00,0x07,0xa2,0x22,0x00,0x0a,
-0x92,0x22,0x00,0x27,0xae,0x20,0x00,0x24,0x08,0x00,0x0d,0x51,0xa2,0x22,0x00,0x04,
-0x08,0x00,0x0d,0xaf,0x24,0x02,0x00,0x06,0x16,0x02,0xff,0x9b,0x3c,0x02,0xb0,0x05,
-0x8e,0x23,0x00,0x2c,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x07,0xa2,0x24,0x00,0x08,
-0x24,0x02,0x00,0x03,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2f,0xae,0x20,0x00,0x2c,
-0x08,0x00,0x0d,0x51,0xa2,0x22,0x00,0x06,0x08,0x00,0x0d,0xbe,0xa2,0x20,0x00,0x0a,
-0x8e,0x22,0x00,0x28,0x24,0x03,0x00,0x01,0x24,0x04,0x00,0x01,0x10,0x44,0x00,0x07,
-0xa2,0x23,0x00,0x08,0x24,0x02,0x00,0x05,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2b,
-0xae,0x20,0x00,0x28,0x08,0x00,0x0d,0x51,0xa2,0x22,0x00,0x05,0x08,0x00,0x0d,0xca,
-0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x12,0x2a,0x02,0x00,0x41,0x10,0x40,0x00,0x09,
-0x24,0x02,0x00,0x80,0x24,0x02,0x00,0x20,0x16,0x02,0xff,0x7b,0x3c,0x02,0xb0,0x05,
-0x24,0x02,0x00,0x12,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x51,
-0xae,0x20,0x00,0x3c,0x16,0x02,0xff,0x74,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10,
-0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x51,0xae,0x20,0x00,0x34,
-0x24,0x02,0x00,0x11,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x51,
-0xae,0x20,0x00,0x38,0x8e,0x24,0x00,0x30,0x24,0x02,0x00,0x03,0x24,0x03,0x00,0x01,
-0x10,0x83,0x00,0x07,0xa2,0x22,0x00,0x08,0x24,0x02,0x00,0x02,0xa2,0x22,0x00,0x0a,
-0x92,0x22,0x00,0x33,0xae,0x20,0x00,0x30,0x08,0x00,0x0d,0x51,0xa2,0x22,0x00,0x07,
-0x08,0x00,0x0d,0xf0,0xa2,0x24,0x00,0x0a,0x8f,0x84,0xb4,0x40,0xae,0x20,0x00,0x34,
-0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x66,0x32,0x10,0x00,0xff,0x08,0x00,0x0d,0x42,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x37,0xf4,
-0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x80,0xa2,0x00,0x15,0x3c,0x06,0xb0,0x05,
-0x10,0x40,0x00,0x0a,0x34,0xc6,0x02,0x54,0x83,0x83,0x8b,0xd4,0x00,0x00,0x00,0x00,
-0xac,0x83,0x00,0x24,0x8c,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x42,
-0x30,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x28,0x8c,0x82,0x00,0x2c,
-0x3c,0x06,0xb0,0x05,0x34,0xc6,0x04,0x50,0x00,0x02,0x18,0x43,0x30,0x63,0x00,0x01,
-0x10,0x40,0x00,0x04,0x30,0x45,0x00,0x01,0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08,
-0xac,0x85,0x00,0x24,0x90,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,
-0x30,0x43,0x00,0x02,0x30,0x42,0x00,0x01,0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08,
-0xac,0x82,0x00,0x24,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd8,
-0x34,0x63,0x00,0x20,0x24,0x42,0x38,0x84,0xac,0x62,0x00,0x00,0xaf,0xb1,0x00,0x1c,
-0xaf,0xbf,0x00,0x20,0xaf,0xb0,0x00,0x18,0x90,0xa6,0x00,0x0a,0x27,0x83,0xb4,0x00,
-0x00,0xa0,0x88,0x21,0x00,0x06,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00,
-0x80,0xa5,0x00,0x11,0x92,0x03,0x00,0x12,0x10,0xa0,0x00,0x04,0xa2,0x20,0x00,0x15,
-0x24,0x02,0x00,0x12,0x10,0xc2,0x00,0xda,0x00,0x00,0x00,0x00,0x82,0x22,0x00,0x12,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x67,0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x12,
-0xa2,0x00,0x00,0x19,0x86,0x23,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x20,0x00,0x43,0x10,0x21,
-0xa0,0x40,0x00,0x00,0x92,0x03,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0xdf,
-0xa2,0x03,0x00,0x16,0x82,0x02,0x00,0x12,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20,
-0x00,0x00,0x00,0x00,0x92,0x23,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x45,
-0x24,0x02,0x00,0x01,0xa2,0x20,0x00,0x04,0x92,0x08,0x00,0x04,0x00,0x00,0x00,0x00,
-0x15,0x00,0x00,0x1e,0x24,0x02,0x00,0x01,0x92,0x07,0x00,0x0a,0xa2,0x02,0x00,0x17,
-0x92,0x02,0x00,0x16,0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xe4,0x10,0x60,0x00,0x03,
-0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,0x11,0x00,0x00,0x05,
-0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,
-0xa2,0x02,0x00,0x16,0x92,0x02,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x08,
-0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x02,0x00,0x14,
-0x8f,0xbf,0x00,0x20,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
-0x96,0x02,0x00,0x00,0x08,0x00,0x0e,0x6c,0xa6,0x02,0x00,0x14,0x92,0x07,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x58,
-0xa2,0x00,0x00,0x17,0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,0x27,0x86,0x90,0x00,
-0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,
-0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,
-0x8c,0x66,0x00,0x08,0x8c,0x45,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xc3,0x20,0x24,
-0x10,0x80,0x00,0x08,0x00,0xa3,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,
-0x10,0x80,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0xa6,0x18,0x2b,0x08,0x00,0x0e,0x58,
-0xa2,0x03,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0xa6,0x18,0x2b,0x08,0x00,0x0e,0x8c,
-0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05,
-0x24,0x02,0x00,0x03,0x14,0x62,0xff,0xb8,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x52,
-0xa2,0x20,0x00,0x07,0x08,0x00,0x0e,0x52,0xa2,0x20,0x00,0x06,0x08,0x00,0x0e,0x52,
-0xa2,0x20,0x00,0x05,0x82,0x22,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x69,
-0x2c,0x62,0x00,0x02,0x10,0x40,0x00,0x49,0x3c,0x02,0xb0,0x09,0x92,0x25,0x00,0x08,
-0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x3b,
-0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,
-0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,
-0xa0,0x83,0x00,0x00,0x86,0x23,0x00,0x0c,0x96,0x26,0x00,0x0c,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80,0x27,0x83,0x90,0x04,0x00,0xa3,0x18,0x21,
-0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x18,0x24,0x07,0x00,0x01,0x93,0x82,0x8b,0x71,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x0a,0x24,0x05,0x00,0x24,
-0x00,0x06,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1b,0x66,0x02,0x00,0x20,0x21,
-0x92,0x02,0x00,0x16,0xa2,0x00,0x00,0x12,0x30,0x42,0x00,0xe7,0x08,0x00,0x0e,0x49,
-0xa2,0x02,0x00,0x16,0xf0,0xc5,0x00,0x06,0x00,0x00,0x28,0x12,0x27,0x82,0x90,0x00,
-0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x49,0x3c,0x04,0x00,0x80,0x96,0x26,0x00,0x0c,
-0x08,0x00,0x0e,0xc9,0x00,0x06,0x2c,0x00,0x27,0x83,0x90,0x10,0x27,0x82,0x90,0x18,
-0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00,0x90,0x65,0x00,0x05,
-0x93,0x82,0x80,0x10,0x00,0x00,0x30,0x21,0x0c,0x00,0x21,0x9a,0xaf,0xa2,0x00,0x10,
-0x96,0x26,0x00,0x0c,0x08,0x00,0x0e,0xc3,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xcd,
-0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,
-0x24,0x02,0x00,0x80,0x08,0x00,0x0e,0xb2,0x00,0xa2,0x10,0x07,0x86,0x26,0x00,0x0c,
-0x3c,0x03,0xb0,0x09,0x34,0x42,0x01,0x72,0x34,0x63,0x01,0x78,0x94,0x47,0x00,0x00,
-0x8c,0x65,0x00,0x00,0x00,0x06,0x10,0xc0,0x00,0x46,0x10,0x21,0x3c,0x04,0xb0,0x09,
-0xae,0x25,0x00,0x1c,0x34,0x84,0x01,0x7c,0x27,0x83,0x90,0x04,0x00,0x02,0x10,0x80,
-0x8c,0x85,0x00,0x00,0x00,0x43,0x10,0x21,0x8c,0x43,0x00,0x18,0xae,0x25,0x00,0x20,
-0xa6,0x27,0x00,0x18,0x8c,0x66,0x00,0x08,0x02,0x20,0x20,0x21,0x0c,0x00,0x0f,0x19,
-0x00,0x00,0x28,0x21,0x86,0x25,0x00,0x18,0x8e,0x26,0x00,0x1c,0x8e,0x27,0x00,0x20,
-0x02,0x20,0x20,0x21,0x0c,0x00,0x1c,0x68,0xaf,0xa2,0x00,0x10,0x08,0x00,0x0e,0x49,
-0xa2,0x02,0x00,0x12,0x92,0x22,0x00,0x08,0x08,0x00,0x0e,0x49,0xa2,0x22,0x00,0x09,
-0xa2,0x20,0x00,0x11,0x80,0x82,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0xac,0x40,0x00,0x00,0x08,0x00,0x0e,0x49,
-0xa0,0x80,0x00,0x50,0x94,0x8a,0x00,0x0c,0x24,0x03,0x00,0x24,0x00,0x80,0x70,0x21,
-0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03,0x24,0x42,0x3c,0x64,0xf1,0x43,0x00,0x06,
-0x34,0x84,0x00,0x20,0x00,0x00,0x18,0x12,0x00,0xa0,0x68,0x21,0xac,0x82,0x00,0x00,
-0x27,0x85,0x90,0x10,0x27,0x82,0x90,0x0f,0x27,0xbd,0xff,0xf8,0x00,0x62,0x60,0x21,
-0x00,0x65,0x58,0x21,0x00,0x00,0xc0,0x21,0x11,0xa0,0x00,0xcc,0x00,0x00,0x78,0x21,
-0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x91,0x87,0x00,0x00,0x80,0x48,0x00,0x04,
-0x03,0xa0,0x60,0x21,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x48,0x80,0x27,0x83,0x90,0x04,0xa3,0xa7,0x00,0x00,
-0x01,0x23,0x18,0x21,0x8c,0x64,0x00,0x18,0x25,0x02,0xff,0xff,0x00,0x48,0x40,0x0b,
-0x8c,0x83,0x00,0x04,0x2d,0x05,0x00,0x07,0x24,0x02,0x00,0x06,0x30,0x63,0x00,0x08,
-0x14,0x60,0x00,0x35,0x00,0x45,0x40,0x0a,0x93,0xa7,0x00,0x00,0x27,0x82,0x90,0x18,
-0x01,0x22,0x10,0x21,0x30,0xe3,0x00,0xf0,0x38,0x63,0x00,0x50,0x30,0xe5,0x00,0xff,
-0x00,0x05,0x20,0x2b,0x00,0x03,0x18,0x2b,0x00,0x64,0x18,0x24,0x90,0x49,0x00,0x00,
-0x10,0x60,0x00,0x16,0x30,0xe4,0x00,0x0f,0x24,0x02,0x00,0x04,0x10,0xa2,0x00,0x9d,
-0x00,0x00,0x00,0x00,0x11,0xa0,0x00,0x3a,0x2c,0xa2,0x00,0x0c,0x10,0x40,0x00,0x02,
-0x24,0x84,0x00,0x0c,0x00,0xe0,0x20,0x21,0x30,0x84,0x00,0xff,0x00,0x04,0x10,0x40,
-0x27,0x83,0xbb,0x1c,0x00,0x44,0x10,0x21,0x00,0x43,0x10,0x21,0x90,0x47,0x00,0x00,
-0x00,0x00,0x00,0x00,0x2c,0xe3,0x00,0x0c,0xa3,0xa7,0x00,0x00,0x10,0x60,0x00,0x02,
-0x24,0xe2,0x00,0x04,0x00,0xe0,0x10,0x21,0xa3,0xa2,0x00,0x00,0x91,0x65,0x00,0x00,
-0x91,0x82,0x00,0x00,0x30,0xa3,0x00,0xff,0x00,0x62,0x10,0x2b,0x10,0x40,0x00,0x0e,
-0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0x60,0x20,0x21,0x30,0xa2,0x00,0x0f,
-0x24,0x44,0x00,0x0c,0x00,0x04,0x10,0x40,0x00,0x44,0x20,0x21,0x27,0x83,0xbb,0x1c,
-0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x02,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05,
-0x00,0x09,0x11,0x00,0xa1,0x85,0x00,0x00,0x93,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x08,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x27,0x83,0xb4,0xa8,0x00,0x43,0x10,0x21,
-0x90,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x83,0x00,0x0c,0x14,0x60,0x00,0x06,
-0x00,0x80,0x10,0x21,0x00,0x18,0x10,0x40,0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00,
-0x00,0x82,0x10,0x21,0x24,0x42,0x00,0x04,0x08,0x00,0x0f,0x7a,0xa1,0x82,0x00,0x00,
-0x8f,0x8d,0x81,0x5c,0x00,0x00,0x00,0x00,0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xd1,0x00,0x00,0x28,0x21,0x00,0x06,0x74,0x82,
-0x30,0xe2,0x00,0xff,0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0xe0,0x10,0x21,
-0x30,0xe2,0x00,0x0f,0x24,0x42,0x00,0x0c,0x30,0x44,0x00,0xff,0xa3,0xa2,0x00,0x00,
-0x24,0x02,0x00,0x0c,0x10,0x82,0x00,0x0d,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x04,0x18,0x40,0x00,0x49,0x10,0x23,0x00,0x64,0x18,0x21,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x27,0x84,0xb4,0xa8,0x00,0x44,0x10,0x21,
-0x90,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xa7,0x00,0x00,0x00,0x0a,0x1c,0x00,
-0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x90,0x04,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00,
-0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x14,0x60,0x00,0x33,
-0x00,0x06,0x14,0x42,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,
-0x00,0x49,0x10,0x23,0x27,0x83,0xb5,0x78,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,
-0x90,0x44,0x00,0x04,0x90,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x64,0xc0,0x24,
-0x93,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xe2,0x00,0x0f,0x10,0x40,0x00,0x0f,
-0x31,0xcf,0x00,0x01,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x84,0x90,0x00,0x00,0x44,0x10,0x21,
-0x84,0x43,0x00,0x06,0x00,0x00,0x00,0x00,0x28,0x63,0x06,0x41,0x14,0x60,0x00,0x04,
-0x30,0xe2,0x00,0xff,0x24,0x07,0x00,0x0f,0xa3,0xa7,0x00,0x00,0x30,0xe2,0x00,0xff,
-0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x06,0x00,0xe0,0x10,0x21,0x00,0x18,0x10,0x40,
-0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x47,0x10,0x21,0x24,0x42,0x00,0x04,
-0xa3,0xa2,0x00,0x00,0x00,0x40,0x38,0x21,0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00,
-0x24,0xa4,0x00,0x01,0x30,0x85,0xff,0xff,0x00,0xa3,0x18,0x2b,0x14,0x60,0xff,0xad,
-0x30,0xe2,0x00,0xff,0x08,0x00,0x0f,0x67,0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0xc8,
-0x30,0x58,0x00,0x01,0x81,0xc2,0x00,0x48,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x73,
-0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0x55,0x00,0x00,0x00,0x00,0x00,0x0a,0x1c,0x00,
-0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x45,0x10,0x21,0x80,0x48,0x00,0x05,0x91,0x67,0x00,0x00,0x08,0x00,0x0f,0x35,
-0x03,0xa0,0x58,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,
-0x24,0x42,0x40,0x04,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0,
-0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28,
-0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0xaf,0xbf,0x00,0x3c,0xaf,0xbe,0x00,0x38,
-0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0x84,0x82,0x00,0x0c,0x27,0x93,0x90,0x04,
-0x3c,0x05,0xb0,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,
-0x00,0x73,0x10,0x21,0x8c,0x5e,0x00,0x18,0x3c,0x02,0x80,0x00,0x34,0xa5,0x00,0x20,
-0x24,0x42,0x40,0x1c,0xac,0xa2,0x00,0x00,0x8f,0xd0,0x00,0x08,0x27,0x95,0x90,0x10,
-0x00,0x75,0x18,0x21,0x00,0x00,0x28,0x21,0x02,0x00,0x30,0x21,0x90,0x71,0x00,0x00,
-0x0c,0x00,0x0f,0x19,0x00,0x80,0xb0,0x21,0x00,0x40,0x90,0x21,0x00,0x10,0x14,0x42,
-0x30,0x54,0x00,0x01,0x02,0x40,0x20,0x21,0x00,0x10,0x14,0x82,0x02,0x80,0x28,0x21,
-0x12,0x51,0x00,0x23,0x00,0x10,0xbf,0xc2,0x86,0xc3,0x00,0x0c,0x30,0x50,0x00,0x01,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21,
-0xa0,0x52,0x00,0x00,0x86,0xc3,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x53,0x30,0x21,0x8c,0xc7,0x00,0x18,
-0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x8c,0xe3,0x00,0x04,0x84,0x46,0x00,0x06,
-0x00,0x03,0x19,0x42,0x0c,0x00,0x08,0xe3,0x30,0x73,0x00,0x01,0x00,0x40,0x88,0x21,
-0x02,0x40,0x20,0x21,0x02,0x80,0x28,0x21,0x16,0xe0,0x00,0x10,0x02,0x00,0x30,0x21,
-0x86,0xc2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,
-0x00,0x03,0x18,0x80,0x27,0x82,0x90,0x08,0x00,0x62,0x18,0x21,0xa4,0x71,0x00,0x04,
-0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,
-0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x86,0xc3,0x00,0x0c,
-0xaf,0xb3,0x00,0x10,0xaf,0xa0,0x00,0x14,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21,0x80,0x47,0x00,0x06,0x00,0x00,0x00,0x00,
-0x24,0xe7,0x00,0x02,0x00,0x07,0x17,0xc2,0x00,0xe2,0x38,0x21,0x00,0x07,0x38,0x43,
-0x00,0x07,0x38,0x40,0x0c,0x00,0x09,0x0a,0x03,0xc7,0x38,0x21,0x08,0x00,0x10,0x48,
-0x02,0x22,0x88,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0,
-0x34,0x63,0x00,0x20,0x24,0x42,0x41,0xa4,0xaf,0xb2,0x00,0x20,0xac,0x62,0x00,0x00,
-0xaf,0xbf,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,
-0x3c,0x02,0xb0,0x03,0x90,0x83,0x00,0x0a,0x34,0x42,0x01,0x04,0x94,0x45,0x00,0x00,
-0x00,0x03,0x18,0x80,0x27,0x82,0xb4,0x00,0x00,0x62,0x18,0x21,0x30,0xa6,0xff,0xff,
-0x8c,0x71,0x00,0x00,0x80,0x85,0x00,0x12,0x30,0xc9,0x00,0xff,0x00,0x06,0x32,0x02,
-0xa4,0x86,0x00,0x44,0xa4,0x89,0x00,0x46,0x82,0x22,0x00,0x12,0x00,0x80,0x90,0x21,
-0x10,0xa0,0x00,0x1b,0xa0,0x80,0x00,0x15,0x00,0xc5,0x10,0x2a,0x10,0x40,0x00,0x14,
-0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x19,0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x20,
-0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x00,0xa0,0x80,0x00,0x12,0x92,0x22,0x00,0x16,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xdf,0xa2,0x22,0x00,0x16,0x8f,0xbf,0x00,0x28,
-0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,
-0x0c,0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x97,0x00,0x00,0x00,0x00,
-0x28,0x42,0x00,0x02,0x10,0x40,0x01,0x76,0x00,0x00,0x28,0x21,0x94,0x87,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x00,0xe0,0x10,0x21,0x00,0x02,0x14,0x00,0x00,0x02,0x14,0x03,
-0x00,0x07,0x24,0x00,0x00,0x04,0x24,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,
-0x00,0x04,0x28,0xc0,0x00,0xa4,0x28,0x21,0x27,0x82,0x90,0x20,0x00,0x03,0x18,0x80,
-0x00,0x62,0x18,0x21,0x00,0x05,0x28,0x80,0x27,0x82,0x90,0x08,0x00,0xa2,0x10,0x21,
-0x8c,0x68,0x00,0x00,0x80,0x44,0x00,0x06,0x27,0x82,0x90,0x10,0x00,0x08,0x1d,0x02,
-0x00,0xa2,0x28,0x21,0x38,0x84,0x00,0x00,0x30,0x63,0x00,0x01,0x01,0x24,0x30,0x0b,
-0x80,0xaa,0x00,0x04,0x80,0xa9,0x00,0x05,0x10,0x60,0x00,0x02,0x00,0x08,0x14,0x02,
-0x30,0x46,0x00,0x0f,0x15,0x20,0x00,0x28,0x01,0x49,0x10,0x21,0x15,0x40,0x00,0x11,
-0x30,0xe3,0xff,0xff,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa8,0x00,0xff,
-0x2d,0x02,0x00,0x04,0x10,0x40,0x01,0x46,0x2d,0x02,0x00,0x10,0x3c,0x04,0xb0,0x05,
-0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x01,0x02,0x10,0x04,
-0x00,0x62,0x18,0x25,0xa0,0x83,0x00,0x00,0x96,0x47,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x30,0xe3,0xff,0xff,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x27,0x84,0x90,0x10,
-0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,
-0x3c,0x04,0xb0,0x00,0x00,0x65,0x18,0x21,0x00,0x64,0x20,0x21,0x94,0x82,0x00,0x00,
-0x82,0x43,0x00,0x10,0x00,0x02,0x14,0x00,0x14,0x60,0x00,0x06,0x00,0x02,0x3c,0x03,
-0x30,0xe2,0x00,0x04,0x14,0x40,0x00,0x04,0x01,0x49,0x10,0x21,0x34,0xe2,0x08,0x00,
-0xa4,0x82,0x00,0x00,0x01,0x49,0x10,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,
-0x00,0x46,0x10,0x2a,0x10,0x40,0x00,0x7c,0x00,0x00,0x00,0x00,0x82,0x42,0x00,0x10,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x86,0x43,0x00,0x0c,
-0x25,0x44,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x04,0x92,0x23,0x00,0x16,
-0x02,0x40,0x20,0x21,0x30,0x63,0x00,0xfb,0x08,0x00,0x10,0x9c,0xa2,0x23,0x00,0x16,
-0x86,0x43,0x00,0x0c,0x25,0x24,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x05,
-0x86,0x45,0x00,0x0c,0x0c,0x00,0x1e,0xea,0x02,0x20,0x20,0x21,0x10,0x40,0x00,0x5a,
-0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,
-0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x4c,0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,
-0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,
-0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,0x92,0x45,0x00,0x08,
-0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x33,0x24,0x02,0x00,0x01,
-0xa2,0x40,0x00,0x04,0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0c,
-0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17,0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x96,0x22,0x00,0x06,0x08,0x00,0x10,0x97,
-0xa6,0x22,0x00,0x14,0x96,0x22,0x00,0x00,0x08,0x00,0x10,0x97,0xa6,0x22,0x00,0x14,
-0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0x11,0x26,0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06,
-0x27,0x86,0x90,0x00,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,
-0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,
-0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00,
-0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04,
-0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,
-0x08,0x00,0x11,0x26,0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,
-0x08,0x00,0x11,0x49,0x00,0x00,0x00,0x00,0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02,
-0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xca,0x00,0x00,0x00,0x00,
-0x08,0x00,0x11,0x21,0xa2,0x40,0x00,0x07,0x08,0x00,0x11,0x21,0xa2,0x40,0x00,0x06,
-0x08,0x00,0x11,0x21,0xa2,0x40,0x00,0x05,0x14,0x40,0xff,0xbe,0x3c,0x04,0xb0,0x05,
-0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,
-0x08,0x00,0x11,0x18,0x00,0xa2,0x10,0x07,0x0c,0x00,0x10,0x07,0x02,0x40,0x20,0x21,
-0x08,0x00,0x10,0x97,0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,
-0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x99,0x2c,0xc2,0x00,0x10,
-0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,
-0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,
-0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x80,
-0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x86,0x43,0x00,0x0c,0x27,0x93,0x90,0x04,
-0x96,0x47,0x00,0x0c,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80,
-0x00,0xb3,0x18,0x21,0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x64,0x00,0x00,0x30,0x21,
-0x00,0x07,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x53,0x10,0x21,0x8c,0x43,0x00,0x18,0x93,0x82,0x8b,0x71,
-0x8c,0x64,0x00,0x04,0x30,0x42,0x00,0x01,0x00,0x04,0x21,0x42,0x14,0x40,0x00,0x4d,
-0x30,0x90,0x00,0x01,0x00,0x07,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1b,0x66,
-0x02,0x20,0x20,0x21,0x96,0x26,0x00,0x06,0x12,0x00,0x00,0x14,0x30,0xc5,0xff,0xff,
-0x02,0x60,0x90,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x52,0x18,0x21,0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0b,
-0x02,0x20,0x20,0x21,0x8c,0x63,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x62,0x00,0x04,
-0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x0c,0x00,0x1b,0x66,0x30,0x50,0x00,0x01,
-0x96,0x26,0x00,0x06,0x16,0x00,0xff,0xef,0x30,0xc5,0xff,0xff,0x92,0x22,0x00,0x04,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0d,0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17,
-0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,
-0xa6,0x26,0x00,0x14,0x92,0x22,0x00,0x16,0x08,0x00,0x10,0x96,0x30,0x42,0x00,0xc3,
-0x96,0x22,0x00,0x00,0x08,0x00,0x11,0xbd,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x11,0xb8,
-0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x30,0xc5,0xff,0xff,0x00,0x05,0x18,0xc0,
-0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x65,0x18,0x21,0x27,0x84,0x90,0x00,
-0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x00,0x03,0x18,0x80,0x8c,0x45,0x00,0x08,
-0x00,0x64,0x18,0x21,0x8c,0x64,0x00,0x08,0x3c,0x02,0x80,0x00,0x00,0xa2,0x38,0x24,
-0x10,0xe0,0x00,0x08,0x00,0x82,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,
-0x10,0xe0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x11,0xb8,
-0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x11,0xdc,
-0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x24,0xf0,0xe5,0x00,0x06,0x00,0x00,0x28,0x12,
-0x27,0x82,0x90,0x00,0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x49,0x00,0x00,0x20,0x21,
-0x96,0x47,0x00,0x0c,0x08,0x00,0x11,0x9a,0x00,0x07,0x2c,0x00,0x27,0x83,0x90,0x10,
-0x27,0x82,0x90,0x18,0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00,
-0x90,0x65,0x00,0x05,0x93,0x82,0x80,0x10,0x24,0x07,0x00,0x01,0x0c,0x00,0x21,0x9a,
-0xaf,0xa2,0x00,0x10,0x96,0x47,0x00,0x0c,0x08,0x00,0x11,0x8d,0x00,0x07,0x1c,0x00,
-0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03,
-0x14,0xa2,0xff,0x7d,0x00,0x00,0x00,0x00,0x08,0x00,0x11,0x7e,0xa2,0x40,0x00,0x07,
-0x08,0x00,0x11,0x7e,0xa2,0x40,0x00,0x06,0x08,0x00,0x11,0x7e,0xa2,0x40,0x00,0x05,
-0x14,0x40,0xff,0x71,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,
-0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x11,0x75,0x00,0xa2,0x10,0x07,
-0x14,0x40,0xfe,0xc3,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,
-0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x10,0xd0,0x00,0xa2,0x10,0x07,
-0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x04,0x00,0x43,0x10,0x21,0x8c,0x47,0x00,0x18,
-0x00,0x00,0x00,0x00,0x8c,0xe6,0x00,0x08,0x0c,0x00,0x0f,0x19,0x00,0x00,0x00,0x00,
-0x02,0x40,0x20,0x21,0x00,0x00,0x28,0x21,0x00,0x00,0x30,0x21,0x00,0x00,0x38,0x21,
-0x0c,0x00,0x1c,0x68,0xaf,0xa2,0x00,0x10,0x00,0x02,0x1e,0x00,0x14,0x60,0xfe,0x6b,
-0xa2,0x22,0x00,0x12,0x92,0x43,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x40,
-0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x92,0x28,0x00,0x04,0x00,0x00,0x00,0x00,
-0x15,0x00,0x00,0x19,0x24,0x02,0x00,0x01,0x92,0x27,0x00,0x0a,0xa2,0x22,0x00,0x17,
-0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x10,0x00,0x00,0x00,0x00,
-0x96,0x22,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x16,
-0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xc0,0x10,0x60,0x00,0x03,0xa2,0x22,0x00,0x16,
-0x34,0x42,0x00,0x01,0xa2,0x22,0x00,0x16,0x11,0x00,0xfe,0x50,0x00,0x00,0x00,0x00,
-0x92,0x22,0x00,0x16,0x08,0x00,0x10,0x96,0x34,0x42,0x00,0x02,0x96,0x22,0x00,0x00,
-0x08,0x00,0x12,0x3f,0xa6,0x22,0x00,0x14,0x92,0x27,0x00,0x0a,0x00,0x00,0x00,0x00,
-0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0x38,0xa2,0x20,0x00,0x17,
-0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06,0x27,0x86,0x90,0x00,0x00,0x04,0x18,0xc0,
-0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,
-0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,
-0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08,
-0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02,
-0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x12,0x38,0xa2,0x23,0x00,0x17,
-0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x12,0x67,0x00,0x00,0x00,0x00,
-0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x03,
-0x14,0x62,0xff,0xbd,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0x32,0xa2,0x40,0x00,0x07,
-0x08,0x00,0x12,0x32,0xa2,0x40,0x00,0x06,0x08,0x00,0x12,0x32,0xa2,0x40,0x00,0x05,
-0x3c,0x02,0x80,0x00,0x00,0x82,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0xa2,0x18,0x24,
-0x10,0x60,0x00,0x04,0x00,0x00,0x10,0x21,0x10,0xc0,0x00,0x02,0x24,0x02,0x00,0x01,
-0x00,0xa4,0x10,0x2b,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xfd,
-0x00,0xa4,0x10,0x2b,0x08,0x00,0x12,0x82,0x00,0x00,0x00,0x00,0x30,0x82,0xff,0xff,
-0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x27,0x84,0x90,0x10,0x00,0x03,0x18,0x80,
-0x00,0x64,0x18,0x21,0x80,0x66,0x00,0x06,0x00,0x02,0x12,0x00,0x3c,0x03,0xb0,0x00,
-0x00,0x46,0x10,0x21,0x00,0x45,0x10,0x21,0x03,0xe0,0x00,0x08,0x00,0x43,0x10,0x21,
-0x27,0xbd,0xff,0xe0,0x30,0x82,0x00,0x7c,0x30,0x84,0xff,0x00,0xaf,0xbf,0x00,0x1c,
-0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x14,0x40,0x00,0x41,
-0x00,0x04,0x22,0x03,0x24,0x02,0x00,0x04,0x3c,0x10,0xb0,0x03,0x8e,0x10,0x00,0x00,
-0x10,0x82,0x00,0x32,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x03,0x32,0x02,0x00,0x20,
-0x08,0x00,0x12,0xa8,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x17,0x3c,0x02,0xb0,0x06,
-0x34,0x42,0x80,0x24,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x67,0x00,0xff,
-0x10,0xe0,0x00,0x23,0x00,0x00,0x88,0x21,0x8f,0x85,0x8f,0xe0,0x00,0x40,0x30,0x21,
-0x94,0xa2,0x00,0x08,0x8c,0xc3,0x00,0x00,0x26,0x31,0x00,0x01,0x24,0x42,0x00,0x02,
-0x30,0x42,0x01,0xff,0x34,0x63,0x01,0x00,0x02,0x27,0x20,0x2a,0xa4,0xa2,0x00,0x08,
-0x14,0x80,0xff,0xf7,0xac,0xc3,0x00,0x00,0x84,0xa3,0x00,0x08,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0x30,0xac,0x43,0x00,0x00,0x27,0x92,0xb4,0x00,0x24,0x11,0x00,0x12,
-0x8e,0x44,0x00,0x00,0x26,0x31,0xff,0xff,0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x03,0x26,0x52,0x00,0x04,0x0c,0x00,0x18,0xd0,0x00,0x00,0x00,0x00,
-0x06,0x21,0xff,0xf7,0x24,0x02,0xff,0xdf,0x02,0x02,0x80,0x24,0x3c,0x01,0xb0,0x03,
-0x0c,0x00,0x13,0x1c,0xac,0x30,0x00,0x00,0x08,0x00,0x12,0xa8,0x00,0x00,0x00,0x00,
-0x8f,0x85,0x8f,0xe0,0x08,0x00,0x12,0xbe,0x00,0x00,0x00,0x00,0x24,0x02,0xff,0x95,
-0x3c,0x03,0xb0,0x03,0x02,0x02,0x80,0x24,0x34,0x63,0x00,0x30,0x3c,0x01,0xb0,0x03,
-0xac,0x30,0x00,0x00,0x0c,0x00,0x12,0xe5,0xac,0x60,0x00,0x00,0x08,0x00,0x12,0xa8,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x50,0x08,0x00,0x12,0xa8,
-0xac,0x46,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4b,0x94,0x3c,0x0b,0xb0,0x03,
-0xad,0x6a,0x00,0x20,0x3c,0x08,0x80,0x01,0x25,0x08,0x00,0x00,0x3c,0x09,0x80,0x01,
-0x25,0x29,0x03,0x50,0x11,0x09,0x00,0x10,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,
-0x25,0x4a,0x4b,0xbc,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x08,0xb0,0x06,
-0x35,0x08,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,
-0x00,0x00,0x00,0x00,0x31,0x29,0x00,0x01,0x00,0x00,0x00,0x00,0x24,0x01,0x00,0x01,
-0x15,0x21,0xff,0xf2,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4b,0xf8,
-0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x02,0xb0,0x03,0x8c,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x34,0x63,0x00,0x40,0x00,0x00,0x00,0x00,0xac,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0x24,0x3c,0x0b,0xb0,0x03,
-0xad,0x6a,0x00,0x20,0x3c,0x02,0x80,0x01,0x24,0x42,0x00,0x00,0x3c,0x03,0x80,0x01,
-0x24,0x63,0x03,0x50,0x3c,0x04,0xb0,0x00,0x8c,0x85,0x00,0x00,0x00,0x00,0x00,0x00,
-0xac,0x45,0x00,0x00,0x24,0x42,0x00,0x04,0x24,0x84,0x00,0x04,0x00,0x43,0x08,0x2a,
-0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00,0x0c,0x00,0x13,0x1c,0x00,0x00,0x00,0x00,
-0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0x70,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,
-0x3c,0x02,0x80,0x01,0x24,0x42,0x03,0x50,0x3c,0x03,0x80,0x01,0x24,0x63,0x3f,0x24,
-0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04,0xac,0x40,0x00,0x08,0xac,0x40,0x00,0x0c,
-0x24,0x42,0x00,0x10,0x00,0x43,0x08,0x2a,0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00,
-0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0xb0,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,
-0x3c,0x1c,0x80,0x01,0x27,0x9c,0x7f,0xf0,0x27,0x9d,0x8b,0xe0,0x00,0x00,0x00,0x00,
-0x27,0x9d,0x8f,0xc8,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0xd4,0x3c,0x0b,0xb0,0x03,
-0xad,0x6a,0x00,0x20,0x40,0x80,0x68,0x00,0x40,0x08,0x60,0x00,0x00,0x00,0x00,0x00,
-0x35,0x08,0xff,0x01,0x40,0x88,0x60,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x15,0x62,
-0x00,0x00,0x00,0x00,0x24,0x84,0xf8,0x00,0x30,0x87,0x00,0x03,0x00,0x04,0x30,0x40,
-0x00,0xc7,0x20,0x23,0x3c,0x02,0xb0,0x0a,0x27,0xbd,0xff,0xe0,0x24,0x03,0xff,0xff,
-0x00,0x82,0x20,0x21,0xaf,0xb1,0x00,0x14,0xac,0x83,0x10,0x00,0xaf,0xbf,0x00,0x18,
-0xaf,0xb0,0x00,0x10,0x00,0xa0,0x88,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x10,0x00,
-0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0xc7,0x10,0x23,0x3c,0x03,0xb0,0x0a,
-0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00,0x0c,0x00,0x13,0x99,0x02,0x20,0x20,0x21,
-0x02,0x11,0x80,0x24,0x00,0x50,0x80,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8,
-0xaf,0xb2,0x00,0x18,0x00,0xa0,0x90,0x21,0x24,0x05,0xff,0xff,0xaf,0xb3,0x00,0x1c,
-0xaf,0xbf,0x00,0x20,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x00,0xc0,0x98,0x21,
-0x12,0x45,0x00,0x23,0x24,0x84,0xf8,0x00,0x30,0x83,0x00,0x03,0x00,0x04,0x10,0x40,
-0x00,0x40,0x88,0x21,0x00,0x60,0x20,0x21,0x00,0x43,0x10,0x23,0x3c,0x03,0xb0,0x0a,
-0x00,0x43,0x10,0x21,0xac,0x45,0x10,0x00,0x00,0x40,0x18,0x21,0x24,0x05,0x00,0x01,
-0x8c,0x62,0x10,0x00,0x00,0x00,0x00,0x00,0x14,0x45,0xff,0xfd,0x3c,0x02,0xb0,0x0a,
-0x02,0x24,0x88,0x23,0x02,0x22,0x88,0x21,0x8e,0x30,0x00,0x00,0x0c,0x00,0x13,0x99,
-0x02,0x40,0x20,0x21,0x00,0x12,0x18,0x27,0x02,0x03,0x80,0x24,0x00,0x53,0x10,0x04,
-0x02,0x02,0x80,0x25,0xae,0x30,0x00,0x00,0x24,0x03,0x00,0x01,0x8e,0x22,0x10,0x00,
-0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x20,
-0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
-0x30,0x82,0x00,0x03,0x00,0x04,0x18,0x40,0x00,0x62,0x18,0x23,0x3c,0x04,0xb0,0x0a,
-0x00,0x64,0x18,0x21,0xac,0x66,0x00,0x00,0x24,0x04,0x00,0x01,0x8c,0x62,0x10,0x00,
-0x00,0x00,0x00,0x00,0x14,0x44,0xff,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x13,0x87,
-0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x21,0x00,0x64,0x10,0x06,0x30,0x42,0x00,0x01,
-0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x20,
-0x14,0x40,0xff,0xf9,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,
-0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x05,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c,0x00,0x80,0x90,0x21,0x00,0xa0,0x80,0x21,
-0x00,0xc0,0x88,0x21,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x01,0x14,0x40,0xff,0xfc,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0xc0,
-0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0,
-0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x03,0x3c,0x02,0xc0,0x00,0x00,0x10,0x1c,0x00,
-0x34,0x42,0x04,0x00,0x3c,0x04,0xb0,0x05,0x3c,0x05,0xb0,0x05,0x24,0x63,0x16,0x09,
-0x02,0x22,0x10,0x21,0x34,0x84,0x04,0x20,0x34,0xa5,0x04,0x24,0x3c,0x06,0xb0,0x05,
-0xac,0x83,0x00,0x00,0x24,0x07,0x00,0x01,0xac,0xa2,0x00,0x00,0x34,0xc6,0x02,0x28,
-0x24,0x02,0x00,0x20,0xae,0x47,0x00,0x3c,0x24,0x04,0x08,0x24,0xa0,0xc2,0x00,0x00,
-0x3c,0x05,0x00,0xc0,0xa2,0x47,0x00,0x11,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01,
-0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01,
-0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x24,0x02,0x00,0x06,0xac,0x82,0x00,0x0c,0xa0,0x80,0x00,0x50,
-0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04,0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x14,
-0xac,0x80,0x00,0x18,0xac,0x80,0x00,0x1c,0xa4,0x80,0x00,0x20,0xac,0x80,0x00,0x24,
-0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c,0xa0,0x80,0x00,0x30,0xa0,0x80,0x00,0x31,
-0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xa0,0x80,0x00,0x3c,0xac,0x82,0x00,0x10,
-0xa0,0x80,0x00,0x44,0xac,0x80,0x00,0x48,0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x4c,
-0x3c,0x04,0xb0,0x06,0x34,0x84,0x80,0x00,0x8c,0x83,0x00,0x00,0x3c,0x02,0x12,0x00,
-0x3c,0x05,0xb0,0x03,0x00,0x62,0x18,0x25,0x34,0xa5,0x00,0x8b,0x24,0x02,0xff,0x80,
-0xac,0x83,0x00,0x00,0x03,0xe0,0x00,0x08,0xa0,0xa2,0x00,0x00,0x3c,0x04,0xb0,0x03,
-0x34,0x84,0x00,0x0b,0x24,0x02,0x00,0x22,0x3c,0x05,0xb0,0x01,0x3c,0x06,0x45,0x67,
-0x3c,0x0a,0xb0,0x09,0xa0,0x82,0x00,0x00,0x34,0xa5,0x00,0x04,0x34,0xc6,0x89,0xaa,
-0x35,0x4a,0x00,0x04,0x24,0x02,0x01,0x23,0x3c,0x0b,0xb0,0x09,0x3c,0x07,0x01,0x23,
-0x3c,0x0c,0xb0,0x09,0x3c,0x01,0xb0,0x01,0xac,0x20,0x00,0x00,0x27,0xbd,0xff,0xe0,
-0xac,0xa0,0x00,0x00,0x35,0x6b,0x00,0x08,0x3c,0x01,0xb0,0x09,0xac,0x26,0x00,0x00,
-0x34,0xe7,0x45,0x66,0xa5,0x42,0x00,0x00,0x35,0x8c,0x00,0x0c,0x24,0x02,0xcd,0xef,
-0x3c,0x0d,0xb0,0x09,0x3c,0x08,0xcd,0xef,0x3c,0x0e,0xb0,0x09,0xad,0x67,0x00,0x00,
-0xaf,0xb7,0x00,0x1c,0xa5,0x82,0x00,0x00,0xaf,0xb6,0x00,0x18,0xaf,0xb5,0x00,0x14,
-0xaf,0xb4,0x00,0x10,0xaf,0xb3,0x00,0x0c,0xaf,0xb2,0x00,0x08,0xaf,0xb1,0x00,0x04,
-0xaf,0xb0,0x00,0x00,0x35,0xad,0x00,0x10,0x35,0x08,0x01,0x22,0x35,0xce,0x00,0x14,
-0x24,0x02,0x89,0xab,0x3c,0x0f,0xb0,0x09,0x3c,0x09,0x89,0xab,0x3c,0x10,0xb0,0x09,
-0x3c,0x11,0xb0,0x09,0x3c,0x12,0xb0,0x09,0x3c,0x13,0xb0,0x09,0x3c,0x14,0xb0,0x09,
-0x3c,0x15,0xb0,0x09,0x3c,0x16,0xb0,0x09,0x3c,0x17,0xb0,0x09,0xad,0xa8,0x00,0x00,
-0x24,0x03,0xff,0xff,0xa5,0xc2,0x00,0x00,0x35,0xef,0x00,0x18,0x35,0x29,0xcd,0xee,
-0x36,0x10,0x00,0x1c,0x36,0x31,0x00,0x20,0x36,0x52,0x00,0x24,0x36,0x73,0x00,0x28,
-0x36,0x94,0x00,0x2c,0x36,0xb5,0x00,0x30,0x36,0xd6,0x00,0x34,0x36,0xf7,0x00,0x38,
-0x24,0x02,0x45,0x67,0xad,0xe9,0x00,0x00,0xa6,0x02,0x00,0x00,0xae,0x23,0x00,0x00,
-0x8f,0xb0,0x00,0x00,0xa6,0x43,0x00,0x00,0x8f,0xb1,0x00,0x04,0xae,0x63,0x00,0x00,
-0x8f,0xb2,0x00,0x08,0xa6,0x83,0x00,0x00,0x8f,0xb3,0x00,0x0c,0xae,0xa3,0x00,0x00,
-0x8f,0xb4,0x00,0x10,0xa6,0xc3,0x00,0x00,0x8f,0xb5,0x00,0x14,0xae,0xe3,0x00,0x00,
-0x7b,0xb6,0x00,0xfc,0x3c,0x18,0xb0,0x09,0x37,0x18,0x00,0x3c,0xa7,0x03,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x34,0x63,0x00,0x20,0x24,0x42,0x51,0x48,0xac,0x62,0x00,0x00,0x8c,0x83,0x00,0x34,
-0x34,0x02,0xff,0xff,0x00,0x43,0x10,0x2a,0x14,0x40,0x01,0x04,0x00,0x80,0x28,0x21,
-0x8c,0x86,0x00,0x08,0x24,0x02,0x00,0x03,0x10,0xc2,0x00,0xf7,0x00,0x00,0x00,0x00,
-0x8c,0xa2,0x00,0x2c,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x4f,0x24,0x02,0x00,0x06,
-0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0x14,0x40,0x00,0xdd,0xac,0xa2,0x00,0x2c,0x24,0x02,0x00,0x01,
-0x10,0xc2,0x00,0xdc,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xc2,0x00,0xca,
-0x00,0x00,0x00,0x00,0x8c,0xa7,0x00,0x04,0x24,0x02,0x00,0x02,0x10,0xe2,0x00,0xc0,
-0x00,0x00,0x00,0x00,0x8c,0xa2,0x00,0x14,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x09,
-0x24,0x02,0x00,0x01,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x05,0xac,0xa2,0x00,0x14,
-0x24,0x02,0x00,0x01,0xac,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x14,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0x04,0x61,0x00,0x19,0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2e,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x12,
-0x3c,0x02,0xb0,0x03,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x42,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x0c,0x3c,0x02,0xb0,0x03,0x80,0xa2,0x00,0x50,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x08,0x3c,0x02,0xb0,0x03,0x14,0xc0,0x00,0x07,
-0x34,0x42,0x00,0x3f,0x24,0x02,0x00,0x0e,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00,
-0x03,0xe0,0x00,0x08,0xa0,0xa3,0x00,0x50,0x34,0x42,0x00,0x3f,0x90,0x44,0x00,0x00,
-0x24,0x03,0x00,0x01,0x10,0x64,0x00,0x7f,0x3c,0x03,0xb0,0x05,0x80,0xa2,0x00,0x31,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18,
-0x8c,0x43,0x00,0x00,0x3c,0x04,0xf0,0x00,0x3c,0x02,0x80,0x00,0x00,0x64,0x18,0x24,
-0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x09,0x03,0xe0,0x00,0x08,0xac,0xa2,0x00,0x00,
-0x8c,0xa2,0x00,0x40,0x00,0x00,0x00,0x00,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0x10,0x60,0x00,0x09,0x3c,0x03,0xb0,0x03,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,
-0x8c,0x43,0x00,0x00,0x3c,0x04,0x00,0x02,0x00,0x64,0x18,0x24,0x14,0x60,0xff,0xf2,
-0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03,0x34,0x63,0x02,0x01,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x80,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,
-0x8c,0xa3,0x00,0x0c,0x00,0x00,0x00,0x00,0xac,0xa3,0x00,0x10,0x3c,0x02,0xb0,0x03,
-0x90,0x42,0x02,0x01,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0xac,0xa2,0x00,0x0c,
-0x90,0xa3,0x00,0x0f,0x24,0x02,0x00,0x0d,0x3c,0x01,0xb0,0x03,0x08,0x00,0x14,0xb2,
-0xa0,0x23,0x02,0x01,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x80,0x90,0x44,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x04,0x1e,0x00,0x00,0x03,0x1e,0x03,0x10,0x60,0x00,0x15,
-0xa0,0xa4,0x00,0x44,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x0b,0x24,0x02,0x00,0x02,
-0x10,0x62,0x00,0x03,0x24,0x03,0x00,0x0d,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x8c,0xa2,0x00,0x0c,0xac,0xa3,0x00,0x00,0x24,0x03,0x00,0x04,0xac,0xa2,0x00,0x10,
-0x03,0xe0,0x00,0x08,0xac,0xa3,0x00,0x0c,0x24,0x02,0x00,0x0d,0xac,0xa2,0x00,0x00,
-0x24,0x03,0x00,0x04,0x24,0x02,0x00,0x06,0xac,0xa3,0x00,0x10,0x03,0xe0,0x00,0x08,
-0xac,0xa2,0x00,0x0c,0x8c,0xa3,0x00,0x38,0x24,0x04,0x00,0x01,0x10,0x64,0x00,0x2d,
-0x24,0x02,0x00,0x02,0x10,0x60,0x00,0x19,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x10,
-0x24,0x02,0x00,0x04,0x10,0x62,0x00,0x04,0x00,0x00,0x00,0x00,0xac,0xa0,0x00,0x38,
-0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x00,0x10,0xe4,0x00,0x07,0x24,0x02,0x00,0x03,
-0x80,0xa2,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x0b,0xac,0xa3,0x00,0x00,
-0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x38,0x08,0x00,0x15,0x04,0xac,0xa2,0x00,0x00,
-0x10,0xe4,0x00,0x02,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x0c,0xac,0xa2,0x00,0x00,
-0x24,0x02,0x00,0x04,0x03,0xe0,0x00,0x08,0xac,0xa2,0x00,0x38,0x10,0xe4,0x00,0x0e,
-0x3c,0x03,0xb0,0x06,0x34,0x63,0x80,0x24,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x06,0xac,0xa2,0x00,0x18,0x24,0x02,0x00,0x02,
-0xac,0xa2,0x00,0x00,0xac,0xa0,0x00,0x18,0x08,0x00,0x15,0x0d,0x24,0x02,0x00,0x01,
-0x08,0x00,0x15,0x1a,0xac,0xa0,0x00,0x00,0x24,0x02,0x00,0x03,0x08,0x00,0x15,0x1a,
-0xac,0xa2,0x00,0x00,0x24,0x03,0x00,0x0b,0xac,0xa2,0x00,0x38,0x03,0xe0,0x00,0x08,
-0xac,0xa3,0x00,0x00,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x01,0x14,0x40,0xff,0x7d,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x42,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x60,0xff,0x78,0x00,0x00,0x00,0x00,
-0x10,0xc0,0xff,0x81,0x24,0x02,0x00,0x0e,0x08,0x00,0x14,0xa7,0x00,0x00,0x00,0x00,
-0x80,0xa2,0x00,0x30,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x3e,0x24,0x02,0x00,0x04,
-0x08,0x00,0x14,0xb2,0x00,0x00,0x00,0x00,0x84,0xa2,0x00,0x20,0x00,0x00,0x00,0x00,
-0x10,0x40,0xff,0x75,0x24,0x02,0x00,0x06,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,
-0x00,0x60,0x10,0x21,0x14,0x40,0xff,0x2b,0xa4,0xa3,0x00,0x20,0x08,0x00,0x14,0xb2,
-0x24,0x02,0x00,0x06,0x8c,0xa2,0x00,0x1c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x66,
-0x24,0x02,0x00,0x05,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x10,0x40,0xff,0x1b,0xac,0xa2,0x00,0x1c,
-0x08,0x00,0x14,0xb2,0x24,0x02,0x00,0x05,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x42,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0x56,
-0x24,0x02,0x00,0x06,0x08,0x00,0x14,0x60,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x0a,
-0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x00,0x27,0xbd,0xff,0xd8,0xaf,0xb0,0x00,0x10,
-0x27,0x90,0x86,0x58,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,
-0x0c,0x00,0x29,0xd5,0xaf,0xb1,0x00,0x14,0xaf,0x90,0x8f,0xe0,0x48,0x02,0x00,0x00,
-0x0c,0x00,0x13,0xf0,0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x1f,0x02,0x00,0x20,0x21,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x3a,0x94,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0xa3,0x83,0x8f,0xe4,0x0c,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x0c,0x00,0x13,0xfb,
-0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x98,0x0c,0x00,0x27,0x59,0x00,0x00,0x00,0x00,
-0x93,0x84,0x80,0x10,0x0c,0x00,0x21,0x3f,0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x18,
-0x0c,0x00,0x06,0xe5,0x00,0x00,0x00,0x00,0x0c,0x00,0x01,0x39,0x00,0x00,0x00,0x00,
-0x27,0x84,0x84,0x40,0x0c,0x00,0x13,0xd9,0x00,0x00,0x00,0x00,0x27,0x82,0x89,0x4c,
-0xaf,0x82,0x84,0x80,0x0c,0x00,0x00,0x5f,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x34,0x63,0x01,0x08,0x3c,0x04,0xb0,0x09,0x3c,0x05,0xb0,0x09,0x8c,0x66,0x00,0x00,
-0x34,0x84,0x01,0x68,0x34,0xa5,0x01,0x40,0x24,0x02,0xc8,0x80,0x24,0x03,0x00,0x0a,
-0xa4,0x82,0x00,0x00,0xa4,0xa3,0x00,0x00,0x3c,0x04,0xb0,0x03,0x8c,0x82,0x00,0x00,
-0x8f,0x85,0x84,0x40,0xaf,0x86,0x84,0x38,0x34,0x42,0x00,0x20,0xac,0x82,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x58,0x8c,0x43,0x00,0x00,0x2c,0xa4,0x00,0x11,
-0x34,0x63,0x01,0x00,0xac,0x43,0x00,0x00,0x10,0x80,0xff,0xfa,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0x80,0x01,0x00,0x05,0x10,0x80,0x24,0x63,0x02,0x00,0x00,0x43,0x10,0x21,
-0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,
-0x27,0x84,0x84,0x98,0x0c,0x00,0x26,0x8e,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x40,
-0x0c,0x00,0x14,0x52,0x00,0x00,0x00,0x00,0x93,0x83,0x81,0xf1,0x24,0x02,0x00,0x01,
-0x10,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0x85,0x84,0x40,0x8f,0x82,0x84,0x74,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x84,0x74,0x08,0x00,0x15,0x9d,
-0x3c,0x02,0xb0,0x03,0x27,0x84,0x84,0x98,0x0c,0x00,0x27,0x0d,0x00,0x00,0x00,0x00,
-0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x98,0x0c,0x00,0x28,0xdd,
-0x00,0x00,0x00,0x00,0xa3,0x82,0x84,0x71,0x8f,0x82,0x84,0x74,0xaf,0x80,0x84,0x40,
-0x24,0x42,0x00,0x01,0xaf,0x82,0x84,0x74,0x08,0x00,0x15,0x9c,0x00,0x00,0x28,0x21,
-0x27,0x84,0x86,0x58,0x0c,0x00,0x19,0x5b,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,
-0x14,0x40,0x00,0x05,0x3c,0x03,0xb0,0x05,0xaf,0x80,0x84,0x40,0xaf,0x80,0x84,0x44,
-0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x6c,0x14,0x40,0x00,0x20,
-0x24,0x02,0x00,0x01,0x8f,0x84,0x84,0x48,0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x20,
-0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x54,0x14,0x40,0x00,0x15,0x24,0x02,0x00,0x01,
-0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x07,0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x03,
-0x24,0x02,0x00,0x01,0xaf,0x82,0x84,0x44,0xaf,0x85,0x84,0x40,0x08,0x00,0x15,0xb6,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,
-0xa7,0x83,0x84,0x60,0x14,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0xaf,0x82,0x84,0x44,0xaf,0x80,0x84,0x40,0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,
-0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x5c,0x14,0x40,0xff,0xf5,0x24,0x02,0x00,0x01,
-0x08,0x00,0x15,0xe1,0x3c,0x03,0xb0,0x09,0x27,0x84,0x86,0x58,0x0c,0x00,0x1a,0xd1,
-0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x70,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xec,
-0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x6c,0x14,0x40,0xff,0xe4,
-0x24,0x02,0x00,0x02,0x8f,0x84,0x84,0x48,0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x12,
-0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x04,0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x04,
-0x08,0x00,0x15,0xed,0x24,0x02,0x00,0x02,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,
-0x00,0x60,0x10,0x21,0xa7,0x83,0x84,0x60,0x14,0x40,0xff,0xf4,0x00,0x00,0x00,0x00,
-0x08,0x00,0x15,0xfc,0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,
-0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x5c,
-0x14,0x40,0xff,0xf7,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x1d,0x24,0x02,0x00,0x02,
-0x27,0x84,0x89,0x18,0x0c,0x00,0x0b,0x55,0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x44,
-0xaf,0x82,0x84,0x5c,0x38,0x64,0x00,0x02,0x00,0x04,0x18,0x0a,0xaf,0x83,0x84,0x44,
-0x14,0x40,0xff,0xad,0x24,0x05,0x00,0x05,0x8f,0x82,0x89,0x58,0xaf,0x80,0x84,0x40,
-0x10,0x40,0x00,0x02,0x24,0x04,0x00,0x01,0xaf,0x84,0x84,0x48,0x93,0x82,0x89,0x66,
-0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x6c,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,
-0x34,0x42,0x00,0x08,0x8c,0x43,0x00,0x00,0x3c,0x04,0x20,0x00,0x00,0x64,0x18,0x24,
-0x10,0x60,0xff,0x65,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xa0,
-0x8c,0x43,0x00,0x00,0x3c,0x04,0x80,0x00,0xaf,0x80,0x89,0x40,0x24,0x63,0x00,0x01,
-0xac,0x43,0x00,0x00,0x3c,0x01,0xb0,0x05,0xac,0x24,0x00,0x08,0xaf,0x80,0x89,0x3c,
-0xaf,0x80,0x89,0x44,0xaf,0x80,0x89,0x48,0xaf,0x80,0x89,0x54,0xaf,0x80,0x89,0x4c,
-0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x90,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x20,0xaf,0x82,0x84,0x5c,0x8f,0x85,0x84,0x5c,
-0x27,0x84,0x89,0x18,0x0c,0x00,0x0d,0x30,0x00,0x00,0x00,0x00,0x00,0x02,0x1e,0x00,
-0xa3,0x82,0x84,0x70,0xaf,0x80,0x84,0x5c,0x10,0x60,0xff,0x8e,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,0xa7,0x83,0x84,0x60,
-0x10,0x40,0x00,0x04,0x24,0x04,0x00,0x02,0xaf,0x84,0x84,0x48,0x08,0x00,0x15,0xfd,
-0x00,0x00,0x00,0x00,0x08,0x00,0x15,0xee,0x24,0x05,0x00,0x06,0x27,0x84,0x84,0x40,
-0x27,0x85,0x89,0x18,0x0c,0x00,0x0d,0xfd,0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x64,
-0xaf,0x80,0x84,0x6c,0x14,0x40,0x00,0x19,0x00,0x40,0x18,0x21,0x8f,0x82,0x84,0x68,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x15,0x24,0x02,0x00,0x02,0x8f,0x83,0x84,0x48,
-0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x0b,0x3c,0x02,0x40,0x00,0x8f,0x83,0x84,0x44,
-0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x02,0x24,0x05,0x00,0x03,0x24,0x05,0x00,0x06,
-0xaf,0x85,0x84,0x40,0x24,0x04,0x00,0x03,0xaf,0x84,0x84,0x48,0x08,0x00,0x15,0xb6,
-0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x14,0x3c,0x01,0xb0,0x05,0xac,0x22,0x00,0x00,
-0xaf,0x80,0x84,0x40,0x08,0x00,0x16,0x96,0x24,0x04,0x00,0x03,0x10,0x60,0x00,0x10,
-0x00,0x00,0x00,0x00,0x27,0x85,0x89,0x18,0x27,0x84,0x84,0x40,0x0c,0x00,0x0e,0x21,
-0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x44,0x24,0x02,0x00,0x01,0xa3,0x80,0x84,0x70,
-0xaf,0x80,0x84,0x48,0x10,0x62,0x00,0x02,0x24,0x05,0x00,0x03,0x24,0x05,0x00,0x04,
-0xaf,0x85,0x84,0x40,0xaf,0x80,0x84,0x64,0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,
-0x83,0x82,0x84,0x90,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,
-0x27,0x84,0x89,0x18,0x0c,0x00,0x10,0x69,0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x44,
-0xa3,0x80,0x84,0x70,0xaf,0x80,0x84,0x40,0xaf,0x80,0x84,0x48,0x14,0x40,0x00,0x03,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0xaf,0x82,0x84,0x44,0xaf,0x80,0x84,0x68,
-0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x40,0x27,0x85,0x89,0x18,
-0x0c,0x00,0x0e,0x21,0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x44,0xa3,0x80,0x84,0x70,
-0xaf,0x80,0x84,0x40,0xaf,0x80,0x84,0x48,0x14,0x40,0xfe,0xeb,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0xaf,0x82,0x84,0x44,0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,
-0x27,0x84,0x89,0x18,0x0c,0x00,0x10,0x69,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0xc6,
-0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x98,0x0c,0x00,0x29,0x73,0x00,0x00,0x00,0x00,
-0x08,0x00,0x15,0xc5,0x00,0x00,0x00,0x00,0x0c,0x00,0x24,0x05,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x26,0xff,0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x11,0x00,0x00,0x00,0x00,
-0x93,0x83,0xbc,0x18,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x2b,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x83,0xbc,0x10,0x8f,0x82,0xbc,0x14,
-0x00,0x83,0x18,0x23,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x23,0x3c,0x02,0xb0,0x03,
-0x24,0x04,0x05,0xa0,0x34,0x42,0x01,0x18,0x8c,0x42,0x00,0x00,0x0c,0x00,0x06,0xd1,
-0x00,0x00,0x00,0x00,0x24,0x04,0x05,0xa4,0x0c,0x00,0x06,0xd1,0x00,0x02,0x84,0x02,
-0x30,0x51,0xff,0xff,0x24,0x04,0x05,0xa8,0x00,0x02,0x94,0x02,0x0c,0x00,0x06,0xd1,
-0x3a,0x10,0xff,0xff,0x3a,0x31,0xff,0xff,0x30,0x42,0xff,0xff,0x2e,0x10,0x00,0x01,
-0x2e,0x31,0x00,0x01,0x3a,0x52,0xff,0xff,0x02,0x11,0x80,0x25,0x2e,0x52,0x00,0x01,
-0x38,0x42,0xff,0xff,0x02,0x12,0x80,0x25,0x2c,0x42,0x00,0x01,0x02,0x02,0x80,0x25,
-0x16,0x00,0x00,0x02,0x24,0x04,0x00,0x02,0x00,0x00,0x20,0x21,0x0c,0x00,0x05,0x6e,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0xaf,0x83,0xbc,0x10,0x0c,0x00,0x01,0xe9,0x00,0x00,0x00,0x00,
-0xaf,0x80,0x84,0x40,0xaf,0x80,0x84,0x74,0x08,0x00,0x15,0x9c,0x00,0x00,0x28,0x21,
-0x27,0x90,0xb4,0x00,0x24,0x11,0x00,0x12,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
-0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x18,0xd0,0x00,0x00,0x00,0x00,0x26,0x31,0xff,0xff,0x06,0x21,0xff,0xf6,
-0x26,0x10,0x00,0x04,0xaf,0x80,0x84,0x40,0x08,0x00,0x15,0xb7,0x00,0x00,0x28,0x21,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x82,0x84,0x38,
-0x00,0x04,0x19,0xc2,0x00,0x02,0x11,0xc2,0x10,0x62,0xff,0xf6,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x02,0x90,0x43,0x00,0x00,0x3c,0x12,0xb0,0x05,
-0xaf,0x84,0x84,0x38,0x30,0x63,0x00,0xff,0x00,0x03,0x11,0x40,0x00,0x43,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0x02,0x99,0x00,0x00,0x00,0x88,0x21,
-0x36,0x52,0x02,0x2c,0x27,0x90,0xb4,0x00,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
-0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x03,0x10,0x40,0x00,0x06,
-0x30,0x62,0x00,0x1c,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x8f,0x85,0x84,0x38,
-0x0c,0x00,0x1e,0x94,0x02,0x60,0x30,0x21,0x8e,0x42,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0x14,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,0x26,0x31,0x00,0x01,
-0x2a,0x22,0x00,0x13,0x14,0x40,0xff,0xec,0x26,0x10,0x00,0x04,0x08,0x00,0x17,0x21,
-0x00,0x00,0x00,0x00,0x8f,0x84,0x84,0x4c,0x27,0x85,0x89,0x18,0x0c,0x00,0x17,0xa4,
-0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x4c,0x24,0x02,0x00,0x04,0x14,0x62,0xfe,0xa5,
-0x00,0x00,0x00,0x00,0x08,0x00,0x15,0xee,0x24,0x05,0x00,0x05,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0x3f,0x90,0x44,0x00,0x00,0x24,0x03,0x00,0x01,0x10,0x64,0x00,0x08,
-0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x18,0x0c,0x00,0x24,0x2c,0x00,0x00,0x00,0x00,
-0x24,0x05,0x00,0x05,0xaf,0x85,0x84,0x40,0x08,0x00,0x15,0xb7,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x14,0x8c,0x44,0x00,0x00,0x0c,0x00,0x24,0x49,
-0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x65,0x24,0x05,0x00,0x05,0x8f,0x82,0x89,0x4c,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,0x8f,0x84,0xb4,0x40,
-0xaf,0x80,0x89,0x4c,0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x66,0x00,0x00,0x00,0x00,
-0x93,0x82,0x8b,0x71,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x02,0x10,0x40,0x00,0x03,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x01,0x57,0x00,0x00,0x20,0x21,0x8f,0x84,0xb4,0x40,
-0x0c,0x00,0x18,0xd0,0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x21,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xff,0x90,0x27,0xbd,0xff,0xe8,0x00,0x80,0x18,0x21,0x34,0x42,0x00,0x01,
-0x27,0x84,0x89,0x18,0x10,0x62,0x00,0x05,0xaf,0xbf,0x00,0x10,0x8f,0xbf,0x00,0x10,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x06,0xe5,
-0x00,0x00,0x00,0x00,0x27,0x84,0x86,0x58,0x0c,0x00,0x18,0x1f,0x00,0x00,0x00,0x00,
-0x27,0x84,0x84,0x40,0x0c,0x00,0x13,0xd9,0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x8b,
-0x00,0x00,0x00,0x00,0x8f,0x82,0x89,0x58,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,
-0x00,0x00,0x18,0x21,0x8f,0x82,0x84,0x48,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x02,
-0x00,0x00,0x00,0x00,0x24,0x03,0x00,0x01,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,
-0x27,0xbd,0xff,0xe0,0x3c,0x06,0xb0,0x03,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,
-0x34,0xc6,0x00,0x5f,0xaf,0xbf,0x00,0x18,0x90,0xc3,0x00,0x00,0x3c,0x07,0xb0,0x03,
-0x34,0xe7,0x00,0x5d,0x34,0x63,0x00,0x01,0x3c,0x09,0xb0,0x03,0x24,0x02,0x00,0x01,
-0xa0,0xc3,0x00,0x00,0x00,0x80,0x80,0x21,0xa0,0xe2,0x00,0x00,0x00,0xa0,0x88,0x21,
-0x35,0x29,0x00,0x5e,0x00,0xe0,0x40,0x21,0x24,0x04,0x00,0x01,0x91,0x22,0x00,0x00,
-0x91,0x03,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x83,0x00,0x03,0x30,0x42,0x00,0x01,
-0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x2c,
-0x24,0x05,0x0f,0x00,0x24,0x02,0x00,0x06,0x12,0x02,0x00,0x08,0x24,0x05,0x00,0x0f,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x02,0x00,0xa0,0x50,0x00,0x00,0x8f,0xbf,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x24,0x04,0x0c,0x04,
-0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x0f,0x24,0x04,0x0d,0x04,0x24,0x05,0x00,0x0f,
-0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x80,0x24,0x05,0x1e,0x00,
-0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x8c,0x24,0x05,0x0f,0x00,
-0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0x30,
-0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x2c,0x3c,0x05,0x00,0x30,
-0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0x30,
-0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x3c,0x3c,0x05,0x00,0x30,
-0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x08,0x00,0x17,0xc5,0x3c,0x02,0xb0,0x03,
-0x24,0x04,0x08,0x8c,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x80,
-0x24,0x05,0x1e,0x00,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x04,0x24,0x04,0x0c,0x04,
-0x24,0x05,0x00,0x0f,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x04,0x24,0x04,0x0d,0x04,
-0x24,0x05,0x00,0x0f,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x24,
-0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x2c,
-0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34,
-0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x3c,0x05,0x00,0x30,
-0x24,0x06,0x00,0x03,0x0c,0x00,0x13,0x5f,0x24,0x04,0x08,0x3c,0x02,0x20,0x20,0x21,
-0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa4,0x24,0x06,0x01,0x07,0x08,0x00,0x17,0xc5,
-0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x73,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x02,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,
-0xa3,0x80,0x81,0x58,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0xa3,0x82,0x81,0x58,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x00,0x80,0x70,0x21,0x34,0x63,0x00,0x20,0x24,0x42,0x60,0x7c,
-0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x30,0xad,0xc0,0x02,0xb8,
-0x8c,0x83,0x00,0x00,0x24,0x02,0x00,0xff,0xa5,0xc0,0x00,0x0a,0x00,0x00,0x30,0x21,
-0xa7,0x82,0x8f,0xf0,0x27,0x88,0x90,0x00,0xa5,0xc3,0x00,0x08,0x3c,0x07,0xb0,0x08,
-0x30,0xc2,0xff,0xff,0x00,0x02,0x20,0xc0,0x24,0xc3,0x00,0x01,0x00,0x82,0x10,0x21,
-0x00,0x60,0x30,0x21,0x00,0x02,0x10,0x80,0x30,0x63,0xff,0xff,0x00,0x48,0x10,0x21,
-0x00,0x87,0x20,0x21,0x28,0xc5,0x00,0xff,0xac,0x83,0x00,0x00,0x14,0xa0,0xff,0xf4,
-0xa4,0x43,0x00,0x00,0x3c,0x02,0xb0,0x08,0x34,0x03,0xff,0xff,0x25,0xc4,0x00,0x0c,
-0x24,0x0a,0x00,0x02,0x34,0x42,0x07,0xf8,0x3c,0x06,0xb0,0x03,0xa7,0x83,0xb3,0xdc,
-0xac,0x43,0x00,0x00,0xaf,0x84,0xb4,0x00,0x34,0xc6,0x00,0x64,0xa0,0x8a,0x00,0x18,
-0x94,0xc5,0x00,0x00,0x8f,0x82,0xb4,0x00,0x25,0xc4,0x00,0x30,0x24,0x08,0x00,0x03,
-0x3c,0x03,0xb0,0x03,0xa0,0x45,0x00,0x21,0x34,0x63,0x00,0x66,0xaf,0x84,0xb4,0x04,
-0xa0,0x88,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x04,0x25,0xc4,0x00,0x54,
-0x25,0xc7,0x00,0x78,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x08,0xa0,0x88,0x00,0x18,
-0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x08,0x25,0xc8,0x00,0x9c,0x24,0x09,0x00,0x01,
-0xa0,0x45,0x00,0x21,0xaf,0x87,0xb4,0x0c,0xa0,0xea,0x00,0x18,0x94,0xc4,0x00,0x00,
-0x8f,0x82,0xb4,0x0c,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x62,0xa0,0x44,0x00,0x21,
-0xaf,0x88,0xb4,0x10,0xa1,0x09,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x10,
-0x25,0xc4,0x00,0xc0,0x3c,0x06,0xb0,0x03,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x14,
-0xa0,0x89,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x14,0x25,0xc4,0x00,0xe4,
-0x34,0xc6,0x00,0x60,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x18,0xa0,0x80,0x00,0x18,
-0x94,0xc5,0x00,0x00,0x8f,0x82,0xb4,0x18,0x25,0xc3,0x01,0x08,0x25,0xc7,0x01,0x2c,
-0xa0,0x45,0x00,0x21,0xaf,0x83,0xb4,0x1c,0xa0,0x60,0x00,0x18,0x94,0xc8,0x00,0x00,
-0x8f,0x82,0xb4,0x1c,0x25,0xc4,0x01,0x50,0x25,0xc5,0x01,0x74,0xa0,0x48,0x00,0x21,
-0x25,0xc6,0x01,0x98,0x25,0xc9,0x01,0xbc,0x25,0xca,0x01,0xe0,0x25,0xcb,0x02,0x04,
-0x25,0xcc,0x02,0x28,0x25,0xcd,0x02,0x4c,0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03,
-0xaf,0x87,0xb4,0x20,0x34,0x63,0x00,0x38,0xa0,0xe0,0x00,0x18,0xaf,0x84,0xb4,0x24,
-0xa0,0x80,0x00,0x18,0xaf,0x85,0xb4,0x28,0xa0,0xa0,0x00,0x18,0xaf,0x86,0xb4,0x2c,
-0xa0,0xc0,0x00,0x18,0xaf,0x89,0xb4,0x30,0xa1,0x20,0x00,0x18,0xaf,0x8a,0xb4,0x34,
-0xa1,0x40,0x00,0x18,0xaf,0x8b,0xb4,0x38,0xa1,0x60,0x00,0x18,0xaf,0x8c,0xb4,0x3c,
-0xa1,0x80,0x00,0x18,0xaf,0x8d,0xb4,0x40,0xa1,0xa2,0x00,0x18,0x94,0x64,0x00,0x00,
-0x8f,0x82,0xb4,0x40,0x25,0xc5,0x02,0x70,0x3c,0x03,0xb0,0x03,0xa0,0x44,0x00,0x21,
-0x24,0x02,0x00,0x11,0xaf,0x85,0xb4,0x44,0x34,0x63,0x00,0x6e,0xa0,0xa2,0x00,0x18,
-0x94,0x64,0x00,0x00,0x8f,0x82,0xb4,0x44,0x25,0xc5,0x02,0x94,0x3c,0x03,0xb0,0x03,
-0xa0,0x44,0x00,0x21,0x24,0x02,0x00,0x12,0xaf,0x85,0xb4,0x48,0x34,0x63,0x00,0x6c,
-0xa0,0xa2,0x00,0x18,0x94,0x64,0x00,0x00,0x8f,0x82,0xb4,0x48,0x24,0x05,0xff,0xff,
-0x24,0x07,0x00,0x01,0xa0,0x44,0x00,0x21,0x24,0x06,0x00,0x12,0x27,0x84,0xb4,0x00,
-0x8c,0x82,0x00,0x00,0x24,0xc6,0xff,0xff,0xa0,0x40,0x00,0x04,0x8c,0x83,0x00,0x00,
-0xa4,0x45,0x00,0x00,0xa4,0x45,0x00,0x02,0xa0,0x60,0x00,0x0a,0x8c,0x82,0x00,0x00,
-0xa4,0x65,0x00,0x06,0xa4,0x65,0x00,0x08,0xa0,0x40,0x00,0x10,0x8c,0x83,0x00,0x00,
-0xa4,0x45,0x00,0x0c,0xa4,0x45,0x00,0x0e,0xa0,0x60,0x00,0x12,0x8c,0x82,0x00,0x00,
-0x00,0x00,0x00,0x00,0xa0,0x40,0x00,0x16,0x8c,0x83,0x00,0x00,0xa4,0x45,0x00,0x14,
-0xa0,0x67,0x00,0x17,0x8c,0x82,0x00,0x00,0x24,0x84,0x00,0x04,0xa0,0x40,0x00,0x20,
-0x04,0xc1,0xff,0xe7,0xac,0x40,0x00,0x1c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x34,0x42,0x00,0x20,0x24,0x63,0x63,0x40,
-0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x10,0x00,0x80,0x60,0x21,0x10,0x40,0x00,0x56,
-0x00,0x00,0x70,0x21,0x97,0x82,0x8f,0xf0,0x94,0x8a,0x00,0x0c,0x27,0x87,0x90,0x00,
-0x00,0x02,0x40,0xc0,0x01,0x02,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,
-0x90,0x8b,0x00,0x18,0xa4,0x4a,0x00,0x00,0x94,0x83,0x00,0x0e,0x39,0x64,0x00,0x10,
-0x2c,0x84,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x34,0x85,0x00,0x02,
-0x39,0x63,0x00,0x11,0x00,0x83,0x28,0x0b,0x34,0xa3,0x00,0x08,0x39,0x64,0x00,0x12,
-0x00,0x02,0x10,0x80,0x00,0xa4,0x18,0x0b,0x00,0x47,0x10,0x21,0x94,0x49,0x00,0x04,
-0x34,0x64,0x00,0x20,0x00,0x6b,0x20,0x0b,0x34,0x83,0x00,0x40,0x39,0x62,0x00,0x01,
-0x00,0x82,0x18,0x0b,0x00,0x09,0x30,0xc0,0x34,0x64,0x00,0x80,0x00,0xc9,0x28,0x21,
-0x39,0x62,0x00,0x02,0x00,0x60,0x68,0x21,0x00,0x82,0x68,0x0a,0x00,0x05,0x28,0x80,
-0x3c,0x02,0xb0,0x08,0x00,0xa7,0x28,0x21,0x00,0xc2,0x30,0x21,0x01,0x02,0x40,0x21,
-0x34,0x03,0xff,0xff,0x35,0xa4,0x01,0x00,0x39,0x62,0x00,0x03,0x2d,0x67,0x00,0x13,
-0xad,0x0a,0x00,0x00,0xa4,0xa3,0x00,0x00,0xac,0xc3,0x00,0x00,0xa7,0x89,0x8f,0xf0,
-0x10,0xe0,0x00,0x0f,0x00,0x82,0x68,0x0a,0x3c,0x03,0x80,0x01,0x00,0x0b,0x10,0x80,
-0x24,0x63,0x02,0x44,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x60,
-0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x00,0x00,0x02,0x74,0x03,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x3a,0x94,0x44,0x00,0x00,0x93,0x83,0x8f,0xe4,
-0x91,0x82,0x00,0x21,0x01,0xc4,0x20,0x21,0x91,0x85,0x00,0x10,0x00,0x04,0x24,0x00,
-0x00,0x62,0x18,0x21,0x00,0x04,0x74,0x03,0x00,0x6e,0x18,0x23,0x00,0x65,0x10,0x2a,
-0x00,0xa2,0x18,0x0a,0x00,0x0d,0x24,0x00,0x3c,0x02,0xb0,0x06,0x24,0x05,0xff,0xff,
-0x00,0x64,0x18,0x25,0x34,0x42,0x80,0x20,0xac,0x43,0x00,0x00,0xa5,0x85,0x00,0x0e,
-0xa1,0x80,0x00,0x10,0xa5,0x85,0x00,0x0c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x62,0x3c,0x03,0xb0,0x03,
-0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x64,0x3c,0x03,0xb0,0x03,0x08,0x00,0x19,0x14,
-0x34,0x63,0x00,0x66,0x3c,0x03,0xb0,0x03,0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x38,
-0x3c,0x03,0xb0,0x03,0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x6e,0x3c,0x03,0xb0,0x03,
-0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x6c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x34,0x63,0x00,0x20,0x24,0x42,0x65,0x08,0x00,0x05,0x28,0x40,0xac,0x62,0x00,0x00,
-0x00,0xa6,0x28,0x21,0x2c,0xe2,0x00,0x10,0x14,0x80,0x00,0x06,0x00,0x00,0x18,0x21,
-0x10,0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0xe0,0x18,0x21,0x03,0xe0,0x00,0x08,
-0x00,0x60,0x10,0x21,0x24,0x02,0x00,0x20,0x10,0xe2,0x00,0x06,0x2c,0xe4,0x00,0x10,
-0x24,0xa2,0x00,0x01,0x10,0x80,0xff,0xf9,0x00,0x02,0x11,0x00,0x08,0x00,0x19,0x4f,
-0x00,0x47,0x18,0x21,0x08,0x00,0x19,0x4f,0x24,0xa3,0x00,0x50,0x27,0xbd,0xff,0xc8,
-0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x30,
-0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,
-0xaf,0xb0,0x00,0x10,0x00,0x80,0x88,0x21,0x84,0x84,0x00,0x08,0x3c,0x05,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x34,0xa5,0x00,0x20,0x24,0x42,0x65,0x6c,0x3c,0x03,0xb0,0x06,
-0x00,0x04,0x20,0x80,0xac,0xa2,0x00,0x00,0x00,0x83,0x20,0x21,0x3c,0x06,0xb0,0x06,
-0x8c,0x82,0x00,0x00,0x34,0xc6,0x80,0x24,0x8c,0x88,0x00,0x00,0x8c,0xc4,0x00,0x00,
-0x96,0x25,0x00,0x08,0x30,0x52,0xff,0xff,0x00,0x08,0x44,0x02,0x34,0x84,0x01,0x00,
-0x3c,0x02,0xb0,0x00,0x00,0x08,0x18,0xc0,0x00,0x12,0x3a,0x00,0xac,0xc4,0x00,0x00,
-0x00,0xe2,0x38,0x21,0xae,0x32,0x02,0xb8,0x00,0x68,0x18,0x21,0x24,0xa5,0x00,0x02,
-0x8c,0xf6,0x00,0x00,0x30,0xa5,0x01,0xff,0x8c,0xf4,0x00,0x04,0x27,0x86,0x90,0x00,
-0x00,0x03,0x18,0x80,0x00,0x12,0x98,0xc0,0xa6,0x25,0x00,0x08,0x00,0x66,0x18,0x21,
-0x02,0x72,0x10,0x21,0x94,0x65,0x00,0x00,0x00,0x02,0x48,0x80,0x01,0x26,0x30,0x21,
-0x24,0x02,0xff,0xff,0x00,0x14,0x1a,0x02,0x27,0x84,0x90,0x10,0xa4,0xc2,0x00,0x02,
-0x30,0x63,0x00,0x1f,0x24,0x02,0x00,0x10,0x01,0x24,0x20,0x21,0xa4,0xc8,0x00,0x04,
-0x8c,0xf0,0x00,0x08,0xa6,0x23,0x00,0x06,0xa6,0x25,0x00,0x0a,0xa0,0x82,0x00,0x06,
-0x86,0x25,0x00,0x06,0x27,0x82,0x90,0x04,0x01,0x22,0x10,0x21,0x24,0x03,0x00,0x13,
-0x10,0xa3,0x00,0xee,0xac,0x47,0x00,0x18,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00,
-0xa6,0x20,0x00,0x02,0x3c,0x02,0xb0,0x03,0x90,0x64,0x00,0x00,0x34,0x42,0x01,0x08,
-0x8c,0x45,0x00,0x00,0x00,0x10,0x1b,0xc2,0x00,0x04,0x20,0x82,0x30,0x63,0x00,0x01,
-0xac,0xc5,0x00,0x08,0x10,0x60,0x00,0xc7,0x30,0x97,0x00,0x01,0x00,0x10,0x16,0x82,
-0x30,0x46,0x00,0x01,0x00,0x10,0x12,0x02,0x00,0x10,0x19,0xc2,0x00,0x10,0x26,0x02,
-0x00,0x10,0x2e,0x42,0x30,0x48,0x00,0x7f,0x24,0x02,0x00,0x01,0x30,0x75,0x00,0x01,
-0x30,0x84,0x00,0x01,0x10,0xc2,0x00,0xb3,0x30,0xa3,0x00,0x01,0x00,0x60,0x28,0x21,
-0x0c,0x00,0x19,0x42,0x01,0x00,0x38,0x21,0x02,0x72,0x18,0x21,0x00,0x03,0x18,0x80,
-0x2c,0x46,0x00,0x54,0x27,0x85,0x90,0x10,0x27,0x84,0x90,0x08,0x00,0x06,0x10,0x0a,
-0x00,0x65,0x28,0x21,0x26,0xa6,0x00,0x02,0x00,0x64,0x18,0x21,0xa0,0xa2,0x00,0x02,
-0xa0,0x66,0x00,0x06,0xa0,0x62,0x00,0x07,0xa0,0xa2,0x00,0x01,0x02,0x72,0x28,0x21,
-0x00,0x05,0x28,0x80,0x27,0x82,0x90,0x04,0x00,0xa2,0x58,0x21,0x8d,0x64,0x00,0x18,
-0x00,0x10,0x15,0xc2,0x30,0x42,0x00,0x01,0x8c,0x83,0x00,0x0c,0x27,0x84,0x90,0x20,
-0x00,0xa4,0x48,0x21,0xa6,0x22,0x00,0x00,0xa6,0x36,0x00,0x04,0x8d,0x26,0x00,0x00,
-0x00,0x03,0x19,0x42,0x3c,0x02,0xff,0xef,0x34,0x42,0xff,0xff,0x30,0x63,0x00,0x01,
-0x00,0xc2,0x40,0x24,0x00,0x03,0x1d,0x00,0x01,0x03,0x40,0x25,0x00,0x08,0x15,0x02,
-0x00,0x14,0x19,0x82,0x00,0x14,0x25,0x82,0x00,0x10,0x34,0x42,0x00,0x10,0x3c,0x82,
-0x00,0x10,0x2c,0x02,0x30,0x42,0x00,0x01,0x30,0xcd,0x00,0x01,0x30,0x6c,0x00,0x01,
-0x30,0xe6,0x00,0x01,0x30,0x8a,0x00,0x03,0x32,0x94,0x00,0x07,0x30,0xa5,0x00,0x01,
-0xad,0x28,0x00,0x00,0x10,0x40,0x00,0x0b,0x32,0x07,0x00,0x7f,0x8d,0x64,0x00,0x18,
-0x3c,0x03,0xff,0xf0,0x34,0x63,0xff,0xff,0x8c,0x82,0x00,0x0c,0x01,0x03,0x18,0x24,
-0x00,0x02,0x13,0x82,0x30,0x42,0x00,0x0f,0x00,0x02,0x14,0x00,0x00,0x62,0x18,0x25,
-0xad,0x23,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x6a,0x00,0x00,0x00,0x00,
-0x15,0x80,0x00,0x03,0x00,0x00,0x00,0x00,0x15,0x40,0x00,0x5b,0x24,0x02,0x00,0x01,
-0x96,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x04,0xa6,0x22,0x00,0x04,
-0x00,0xa0,0x20,0x21,0x0c,0x00,0x19,0x42,0x01,0xa0,0x28,0x21,0x02,0x72,0x18,0x21,
-0x00,0x03,0x40,0x80,0x2c,0x45,0x00,0x54,0x27,0x84,0x90,0x10,0x01,0x04,0x20,0x21,
-0x00,0x05,0x10,0x0a,0xa0,0x82,0x00,0x00,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05,
-0x96,0x23,0x00,0x04,0x27,0x82,0x90,0x00,0x01,0x02,0x10,0x21,0xa4,0x43,0x00,0x06,
-0x27,0x82,0x90,0x04,0x92,0x26,0x00,0x01,0x01,0x02,0x10,0x21,0x8c,0x45,0x00,0x18,
-0x27,0x83,0x90,0x20,0x01,0x03,0x18,0x21,0xa0,0x60,0x00,0x00,0xa0,0x86,0x00,0x07,
-0x94,0xa2,0x00,0x10,0x24,0x03,0x00,0x04,0x30,0x42,0x00,0x0f,0x10,0x43,0x00,0x36,
-0x24,0xa5,0x00,0x10,0x94,0xa3,0x00,0x16,0x27,0x87,0x90,0x18,0x01,0x07,0x10,0x21,
-0xa4,0x43,0x00,0x02,0x94,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,
-0x14,0x40,0x00,0x24,0x02,0x72,0x20,0x21,0x94,0xa2,0x00,0x00,0x24,0x03,0x00,0xa4,
-0x30,0x42,0x00,0xff,0x10,0x43,0x00,0x1f,0x00,0x00,0x00,0x00,0x94,0xa2,0x00,0x00,
-0x24,0x03,0x00,0x88,0x30,0x42,0x00,0x88,0x10,0x43,0x00,0x14,0x02,0x72,0x18,0x21,
-0x27,0x84,0x90,0x20,0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0x00,
-0x3c,0x04,0x00,0x80,0x00,0x44,0x10,0x25,0xac,0x62,0x00,0x00,0x02,0x72,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0xa0,0x54,0x00,0x00,0x8f,0xbf,0x00,0x30,
-0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,
-0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x94,0xa2,0x00,0x18,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x60,0x10,0x40,0xff,0xe9,0x02,0x72,0x18,0x21,
-0x02,0x72,0x20,0x21,0x27,0x82,0x90,0x20,0x00,0x04,0x20,0x80,0x00,0x82,0x20,0x21,
-0x8c,0x83,0x00,0x00,0x3c,0x02,0xff,0x7f,0x34,0x42,0xff,0xff,0x00,0x62,0x18,0x24,
-0x08,0x00,0x1a,0x37,0xac,0x83,0x00,0x00,0x27,0x87,0x90,0x18,0x01,0x07,0x10,0x21,
-0x08,0x00,0x1a,0x21,0xa4,0x40,0x00,0x02,0x11,0x42,0x00,0x07,0x00,0x00,0x00,0x00,
-0x2d,0x42,0x00,0x02,0x14,0x40,0xff,0xa7,0x00,0xa0,0x20,0x21,0x96,0x22,0x00,0x04,
-0x08,0x00,0x19,0xff,0x24,0x42,0x00,0x0c,0x96,0x22,0x00,0x04,0x08,0x00,0x19,0xff,
-0x24,0x42,0x00,0x08,0x16,0xe6,0xff,0x96,0x3c,0x02,0xff,0xfb,0x8d,0x63,0x00,0x18,
-0x34,0x42,0xff,0xff,0x02,0x02,0x10,0x24,0xac,0x62,0x00,0x08,0x08,0x00,0x19,0xf8,
-0x00,0x00,0x30,0x21,0x16,0xe6,0xff,0x4e,0x00,0x60,0x28,0x21,0x3c,0x02,0xfb,0xff,
-0x34,0x42,0xff,0xff,0x02,0x02,0x10,0x24,0xac,0xe2,0x00,0x08,0x08,0x00,0x19,0xb7,
-0x00,0x00,0x30,0x21,0x93,0x87,0xbb,0x14,0x00,0x10,0x1e,0x42,0x00,0x10,0x26,0x82,
-0x27,0x82,0x90,0x08,0x2c,0xe5,0x00,0x0c,0x01,0x22,0x48,0x21,0x30,0x63,0x00,0x01,
-0x30,0x86,0x00,0x01,0x14,0xa0,0x00,0x06,0x00,0xe0,0x40,0x21,0x00,0x03,0x10,0x40,
-0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0xe2,0x10,0x21,0x24,0x48,0x00,0x04,
-0x02,0x72,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x84,0x90,0x10,0x27,0x83,0x90,0x08,
-0x00,0x44,0x20,0x21,0x00,0x43,0x10,0x21,0xa1,0x28,0x00,0x07,0xa0,0x40,0x00,0x06,
-0xa0,0x80,0x00,0x02,0x08,0x00,0x19,0xc7,0xa0,0x80,0x00,0x01,0x24,0x02,0x00,0x01,
-0xa6,0x22,0x00,0x02,0x0c,0x00,0x01,0xc2,0x00,0xe0,0x20,0x21,0x08,0x00,0x1a,0x3b,
-0x00,0x00,0x00,0x00,0x30,0xa7,0xff,0xff,0x00,0x07,0x18,0xc0,0x00,0x67,0x18,0x21,
-0x3c,0x06,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x6a,0x44,0x27,0x85,0x90,0x10,
-0x00,0x03,0x18,0x80,0x34,0xc6,0x00,0x20,0x00,0x65,0x18,0x21,0xac,0xc2,0x00,0x00,
-0x80,0x62,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x29,0x00,0x80,0x28,0x21,
-0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,0x30,0x43,0x00,0x01,
-0x14,0x60,0x00,0x02,0xa0,0x82,0x00,0x16,0xa0,0x80,0x00,0x17,0x90,0xa2,0x00,0x04,
-0x3c,0x03,0xb0,0x03,0x27,0x86,0x90,0x00,0x14,0x40,0x00,0x06,0x34,0x63,0x00,0x20,
-0x24,0x02,0x00,0x01,0xa0,0xa2,0x00,0x04,0xa4,0xa7,0x00,0x02,0x03,0xe0,0x00,0x08,
-0xa4,0xa7,0x00,0x00,0x94,0xa4,0x00,0x02,0x3c,0x02,0x80,0x01,0x24,0x42,0x82,0x6c,
-0xac,0x62,0x00,0x00,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,
-0x00,0x66,0x18,0x21,0x94,0x62,0x00,0x04,0xa4,0x67,0x00,0x02,0x3c,0x03,0xb0,0x08,
-0x00,0x02,0x20,0xc0,0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,
-0x00,0x83,0x20,0x21,0xa4,0x47,0x00,0x00,0xac,0x87,0x00,0x00,0x90,0xa2,0x00,0x04,
-0xa4,0xa7,0x00,0x02,0x24,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xa0,0xa2,0x00,0x04,
-0x90,0x82,0x00,0x16,0x24,0x85,0x00,0x06,0x34,0x42,0x00,0x01,0x30,0x43,0x00,0x02,
-0x14,0x60,0xff,0xda,0xa0,0x82,0x00,0x16,0x24,0x02,0x00,0x01,0x08,0x00,0x1a,0xa7,
-0xa0,0x82,0x00,0x17,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x00,0x80,0x38,0x21,
-0x84,0x84,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x3c,0x0a,0xb0,0x06,
-0x34,0x63,0x00,0x20,0x24,0x42,0x6b,0x44,0x3c,0x0b,0xb0,0x08,0x27,0x89,0x90,0x00,
-0x34,0x0c,0xff,0xff,0x35,0x4a,0x80,0x20,0x10,0x80,0x00,0x30,0xac,0x62,0x00,0x00,
-0x97,0x82,0x8f,0xf0,0x94,0xe6,0x02,0xba,0x00,0x02,0x18,0xc0,0x00,0x6b,0x28,0x21,
-0xac,0xa6,0x00,0x00,0x8c,0xe4,0x02,0xb8,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,
-0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x21,
-0x94,0x48,0x00,0x04,0x00,0x69,0x18,0x21,0xa4,0x66,0x00,0x00,0x00,0x08,0x28,0xc0,
-0x00,0xab,0x10,0x21,0xac,0x4c,0x00,0x00,0x8c,0xe4,0x02,0xb8,0x27,0x82,0x90,0x04,
-0x00,0xa8,0x28,0x21,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,
-0x00,0x62,0x10,0x21,0x8c,0x46,0x00,0x18,0x27,0x84,0x90,0x10,0x00,0x64,0x18,0x21,
-0x8c,0xc2,0x00,0x00,0x80,0x67,0x00,0x06,0x00,0x05,0x28,0x80,0x30,0x42,0xff,0xff,
-0x00,0x47,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b,0x00,0x02,0x12,0x02,
-0x00,0x43,0x10,0x21,0x3c,0x04,0x00,0x04,0x00,0xa9,0x28,0x21,0x00,0x44,0x10,0x25,
-0xa4,0xac,0x00,0x00,0xad,0x42,0x00,0x00,0xa7,0x88,0x8f,0xf0,0x8f,0xbf,0x00,0x10,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x84,0xe3,0x00,0x06,
-0x27,0x82,0xb4,0x00,0x94,0xe5,0x02,0xba,0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,
-0x8c,0x64,0x00,0x00,0x0c,0x00,0x1a,0x91,0x00,0x00,0x00,0x00,0x08,0x00,0x1b,0x0b,
-0x00,0x00,0x00,0x00,0x94,0x88,0x00,0x00,0x00,0x80,0x58,0x21,0x27,0x8a,0x90,0x00,
-0x00,0x08,0x18,0xc0,0x00,0x68,0x18,0x21,0x3c,0x04,0xb0,0x03,0x00,0x03,0x18,0x80,
-0x3c,0x02,0x80,0x00,0x00,0x6a,0x18,0x21,0x34,0x84,0x00,0x20,0x24,0x42,0x6c,0x64,
-0x30,0xa5,0xff,0xff,0xac,0x82,0x00,0x00,0x94,0x67,0x00,0x02,0x11,0x05,0x00,0x35,
-0x24,0x04,0x00,0x01,0x91,0x66,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x86,0x10,0x2a,
-0x10,0x40,0x00,0x10,0x00,0xc0,0x48,0x21,0x3c,0x0d,0xb0,0x03,0x01,0x40,0x60,0x21,
-0x35,0xad,0x00,0x20,0x10,0xe5,0x00,0x0d,0x24,0x84,0x00,0x01,0x00,0x07,0x10,0xc0,
-0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x80,0x01,0x20,0x30,0x21,0x00,0x4a,0x10,0x21,
-0x00,0x86,0x18,0x2a,0x00,0xe0,0x40,0x21,0x94,0x47,0x00,0x02,0x14,0x60,0xff,0xf5,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x10,0x21,0x00,0x08,0x20,0xc0,
-0x00,0x88,0x20,0x21,0x24,0xc2,0xff,0xff,0x00,0x04,0x20,0x80,0xa1,0x62,0x00,0x04,
-0x00,0x8c,0x20,0x21,0x94,0x83,0x00,0x04,0x00,0x07,0x10,0xc0,0x00,0x47,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x4c,0x10,0x21,0x00,0x03,0x28,0xc0,0x94,0x46,0x00,0x02,
-0x00,0xa3,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x6c,0x18,0x21,0xa4,0x66,0x00,0x00,
-0xa4,0x86,0x00,0x02,0x95,0x64,0x00,0x02,0x3c,0x03,0xb0,0x08,0x3c,0x02,0x80,0x01,
-0x00,0xa3,0x28,0x21,0x24,0x42,0x82,0x6c,0xad,0xa2,0x00,0x00,0x10,0x87,0x00,0x03,
-0xac,0xa6,0x00,0x00,0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01,0x08,0x00,0x1b,0x59,
-0xa5,0x68,0x00,0x02,0x91,0x62,0x00,0x04,0xa5,0x67,0x00,0x00,0x24,0x42,0xff,0xff,
-0x30,0x43,0x00,0xff,0x14,0x60,0xff,0xf7,0xa1,0x62,0x00,0x04,0x24,0x02,0xff,0xff,
-0x08,0x00,0x1b,0x59,0xa5,0x62,0x00,0x02,0x00,0x05,0x40,0xc0,0x01,0x05,0x30,0x21,
-0x27,0xbd,0xff,0xd8,0x00,0x06,0x30,0x80,0x27,0x82,0x90,0x04,0xaf,0xb2,0x00,0x18,
-0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb0,0x00,0x10,
-0x00,0xc2,0x10,0x21,0x8c,0x47,0x00,0x18,0x00,0xa0,0x90,0x21,0x3c,0x02,0x80,0x00,
-0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20,0x24,0x42,0x6d,0x98,0xac,0xa2,0x00,0x00,
-0x27,0x83,0x90,0x10,0x00,0xc3,0x30,0x21,0x8c,0xe2,0x00,0x00,0x80,0xc5,0x00,0x06,
-0x00,0x80,0x88,0x21,0x30,0x42,0xff,0xff,0x00,0x45,0x10,0x21,0x30,0x43,0x00,0xff,
-0x10,0x60,0x00,0x02,0x00,0x02,0x12,0x02,0x24,0x42,0x00,0x01,0x30,0x53,0x00,0xff,
-0x01,0x12,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,
-0x80,0x44,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0x4b,0x26,0x24,0x00,0x06,
-0x32,0x50,0xff,0xff,0x02,0x20,0x20,0x21,0x0c,0x00,0x1b,0x19,0x02,0x00,0x28,0x21,
-0x92,0x22,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x2e,0x3c,0x03,0xb0,0x08,
-0x3c,0x09,0x80,0x01,0x27,0x88,0x90,0x00,0xa6,0x32,0x00,0x0c,0x00,0x10,0x20,0xc0,
-0x00,0x90,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04,
-0x3c,0x03,0xb0,0x08,0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x48,0x10,0x21,0x00,0xa3,0x28,0x21,0x25,0x26,0x82,0x6c,
-0x34,0x03,0xff,0xff,0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02,
-0xa4,0x43,0x00,0x00,0xac,0xa3,0x00,0x00,0x92,0x22,0x00,0x10,0x92,0x23,0x00,0x0a,
-0xa6,0x32,0x00,0x0e,0x02,0x62,0x10,0x21,0x14,0x60,0x00,0x05,0xa2,0x22,0x00,0x10,
-0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfe,0xa2,0x22,0x00,0x16,
-0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,
-0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd,0xa2,0x22,0x00,0x16,
-0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x28,0x96,0x22,0x00,0x0e,0x27,0x88,0x90,0x00,0x00,0x02,0x20,0xc0,
-0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04,
-0x3c,0x06,0xb0,0x03,0x3c,0x09,0x80,0x01,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21,0x00,0x48,0x10,0x21,0x34,0xc6,0x00,0x20,
-0x25,0x23,0x82,0x6c,0xac,0xc3,0x00,0x00,0xa4,0x50,0x00,0x00,0xac,0xb0,0x00,0x00,
-0x08,0x00,0x1b,0x97,0xa4,0x90,0x00,0x02,0x08,0x00,0x1b,0x8e,0x32,0x50,0xff,0xff,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x6f,0x60,0x34,0x63,0x00,0x20,
-0xac,0x62,0x00,0x00,0x90,0x82,0x00,0x04,0x97,0xaa,0x00,0x12,0x00,0x80,0x60,0x21,
-0x30,0xa8,0xff,0xff,0x00,0x4a,0x20,0x23,0x34,0x09,0xff,0xff,0x30,0xcf,0xff,0xff,
-0x30,0xee,0xff,0xff,0x11,0x09,0x00,0x73,0xa1,0x84,0x00,0x04,0x00,0x0e,0xc0,0xc0,
-0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,0x03,0x0e,0x20,0x21,0x27,0x8d,0x90,0x00,
-0x00,0x04,0x20,0x80,0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x00,0x8d,0x20,0x21,
-0x94,0x86,0x00,0x02,0x94,0x43,0x00,0x04,0x3c,0x19,0x80,0x01,0xa4,0x46,0x00,0x02,
-0x00,0x03,0x28,0xc0,0x00,0xa3,0x18,0x21,0x94,0x87,0x00,0x02,0x3c,0x02,0xb0,0x08,
-0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x21,0x00,0x6d,0x18,0x21,0x27,0x22,0x82,0x6c,
-0x3c,0x01,0xb0,0x03,0xac,0x22,0x00,0x20,0xa4,0x66,0x00,0x00,0x10,0xe9,0x00,0x57,
-0xac,0xa6,0x00,0x00,0x01,0xe0,0x30,0x21,0x11,0x40,0x00,0x1d,0x00,0x00,0x48,0x21,
-0x01,0x40,0x38,0x21,0x27,0x8b,0x90,0x04,0x27,0x8a,0x90,0x10,0x00,0x06,0x40,0xc0,
-0x01,0x06,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x6b,0x10,0x21,0x8c,0x44,0x00,0x18,
-0x00,0x6a,0x18,0x21,0x80,0x65,0x00,0x06,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0xff,0xff,0x00,0x45,0x10,0x21,0x30,0x44,0x00,0xff,0x00,0x02,0x12,0x02,
-0x01,0x22,0x18,0x21,0x24,0x62,0x00,0x01,0x14,0x80,0x00,0x02,0x30,0x49,0x00,0xff,
-0x30,0x69,0x00,0xff,0x01,0x06,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,
-0x24,0xe7,0xff,0xff,0x94,0x46,0x00,0x02,0x14,0xe0,0xff,0xe9,0x00,0x06,0x40,0xc0,
-0x91,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20,0x3c,0x06,0xb0,0x03,
-0xa5,0x8f,0x00,0x0c,0x03,0x0e,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21,
-0x94,0x82,0x00,0x04,0x3c,0x03,0xb0,0x08,0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0,
-0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x00,0xa3,0x28,0x21,
-0x27,0x26,0x82,0x6c,0x34,0x03,0xff,0xff,0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00,
-0xa4,0x83,0x00,0x02,0xa4,0x43,0x00,0x00,0xac,0xa3,0x00,0x00,0x91,0x82,0x00,0x10,
-0x91,0x83,0x00,0x04,0xa5,0x8e,0x00,0x0e,0x01,0x22,0x10,0x21,0x14,0x60,0x00,0x05,
-0xa1,0x82,0x00,0x10,0x91,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd,
-0xa1,0x82,0x00,0x16,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x95,0x82,0x00,0x0e,
-0x3c,0x03,0xb0,0x08,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,
-0x00,0x8d,0x20,0x21,0x94,0x82,0x00,0x04,0x34,0xc6,0x00,0x20,0x27,0x27,0x82,0x6c,
-0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21,
-0x00,0x4d,0x10,0x21,0xac,0xc7,0x00,0x00,0xa4,0x8f,0x00,0x02,0xa4,0x4f,0x00,0x00,
-0xac,0xaf,0x00,0x00,0x08,0x00,0x1c,0x26,0x03,0x0e,0x20,0x21,0x08,0x00,0x1c,0x01,
-0xa5,0x88,0x00,0x02,0x00,0x0e,0xc0,0xc0,0x03,0x0e,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x8d,0x90,0x00,0x00,0x4d,0x10,0x21,0x94,0x43,0x00,0x02,0x30,0x84,0x00,0xff,
-0x14,0x80,0x00,0x05,0xa5,0x83,0x00,0x00,0x24,0x02,0xff,0xff,0x3c,0x19,0x80,0x01,
-0x08,0x00,0x1c,0x01,0xa5,0x82,0x00,0x02,0x08,0x00,0x1c,0x01,0x3c,0x19,0x80,0x01,
-0x3c,0x08,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0x78,0x35,0x08,0x00,0x20,
-0x24,0x42,0x71,0xa0,0xaf,0xb2,0x00,0x68,0xaf,0xb1,0x00,0x64,0xaf,0xb0,0x00,0x60,
-0xad,0x02,0x00,0x00,0xaf,0xbf,0x00,0x84,0xaf,0xbe,0x00,0x80,0xaf,0xb7,0x00,0x7c,
-0xaf,0xb6,0x00,0x78,0xaf,0xb5,0x00,0x74,0xaf,0xb4,0x00,0x70,0xaf,0xb3,0x00,0x6c,
-0xaf,0xa4,0x00,0x88,0x90,0x83,0x00,0x0a,0x27,0x82,0xb4,0x00,0xaf,0xa6,0x00,0x90,
-0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x8c,0x63,0x00,0x00,0xaf,0xa7,0x00,0x94,
-0x27,0x86,0x90,0x04,0xaf,0xa3,0x00,0x1c,0x94,0x63,0x00,0x14,0x30,0xb1,0xff,0xff,
-0x24,0x08,0x00,0x01,0x00,0x03,0x20,0xc0,0xaf,0xa3,0x00,0x18,0x00,0x83,0x18,0x21,
-0xaf,0xa4,0x00,0x54,0x00,0x03,0x18,0x80,0x27,0x84,0x90,0x10,0x00,0x64,0x20,0x21,
-0x80,0x82,0x00,0x06,0x00,0x66,0x18,0x21,0x8c,0x66,0x00,0x18,0x24,0x42,0x00,0x02,
-0x00,0x02,0x1f,0xc2,0x8c,0xc4,0x00,0x08,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,
-0x00,0x02,0x10,0x40,0x00,0x04,0x2f,0xc2,0x00,0x04,0x1c,0x82,0x00,0xc2,0x38,0x21,
-0x00,0x04,0x24,0x42,0x8f,0xa2,0x00,0x1c,0x30,0x63,0x00,0x01,0x30,0x84,0x00,0x01,
-0xaf,0xa5,0x00,0x3c,0xaf,0xa3,0x00,0x34,0xaf,0xa4,0x00,0x38,0xaf,0xa0,0x00,0x40,
-0xaf,0xa0,0x00,0x44,0xaf,0xa0,0x00,0x50,0xaf,0xa8,0x00,0x20,0x80,0x42,0x00,0x12,
-0x8f,0xb2,0x00,0x18,0xaf,0xa2,0x00,0x28,0x8c,0xd0,0x00,0x0c,0x14,0xa0,0x01,0xe4,
-0x00,0x60,0x30,0x21,0x00,0x10,0x10,0x82,0x30,0x45,0x00,0x07,0x10,0xa0,0x00,0x11,
-0xaf,0xa0,0x00,0x30,0x8f,0xa4,0x00,0x98,0x27,0x82,0x80,0x1c,0x00,0x04,0x18,0x40,
-0x00,0x62,0x18,0x21,0x24,0xa2,0x00,0x06,0x8f,0xa5,0x00,0x20,0x94,0x64,0x00,0x00,
-0x00,0x45,0x10,0x04,0x00,0x44,0x00,0x1a,0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x0d,0x00,0x00,0x10,0x12,0x24,0x42,0x00,0x20,0x30,0x42,0xff,0xfc,
-0xaf,0xa2,0x00,0x30,0x8f,0xa3,0x00,0x18,0x8f,0xa4,0x00,0x28,0x34,0x02,0xff,0xff,
-0xaf,0xa0,0x00,0x2c,0xaf,0xa2,0x00,0x48,0xaf,0xa3,0x00,0x4c,0x00,0x60,0xf0,0x21,
-0x00,0x00,0xb8,0x21,0x18,0x80,0x00,0x48,0xaf,0xa0,0x00,0x24,0x00,0x11,0x89,0x02,
-0xaf,0xb1,0x00,0x58,0x00,0x80,0xa8,0x21,0x00,0x12,0x10,0xc0,0x00,0x52,0x18,0x21,
-0x00,0x03,0x80,0x80,0x27,0x85,0x90,0x00,0x02,0x40,0x20,0x21,0x00,0x40,0xa0,0x21,
-0x02,0x05,0x10,0x21,0x94,0x56,0x00,0x02,0x0c,0x00,0x12,0x8b,0x00,0x00,0x28,0x21,
-0x90,0x42,0x00,0x00,0x24,0x03,0x00,0x08,0x30,0x42,0x00,0x0c,0x10,0x43,0x01,0x9e,
-0x24,0x04,0x00,0x01,0x24,0x02,0x00,0x01,0x10,0x82,0x01,0x7c,0x3c,0x02,0xb0,0x03,
-0x8f,0xa6,0x00,0x88,0x34,0x42,0x01,0x04,0x84,0xc5,0x00,0x0c,0x02,0x92,0x18,0x21,
-0x94,0x46,0x00,0x00,0x00,0x05,0x20,0xc0,0x00,0x85,0x20,0x21,0x00,0x03,0x18,0x80,
-0x27,0x82,0x90,0x10,0x27,0x85,0x90,0x08,0x00,0x65,0x28,0x21,0x00,0x62,0x18,0x21,
-0x80,0x71,0x00,0x05,0x80,0x73,0x00,0x04,0x8f,0xa3,0x00,0x88,0x30,0xd0,0xff,0xff,
-0x00,0x10,0x3a,0x03,0x32,0x08,0x00,0xff,0x27,0x82,0x90,0x20,0x00,0x04,0x20,0x80,
-0x80,0xa6,0x00,0x06,0x00,0x82,0x20,0x21,0xa4,0x67,0x00,0x44,0xa4,0x68,0x00,0x46,
-0x8c,0x84,0x00,0x00,0x38,0xc6,0x00,0x00,0x01,0x00,0x80,0x21,0x00,0x04,0x15,0x02,
-0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x03,0x00,0xe6,0x80,0x0a,0x00,0x04,0x14,0x02,
-0x30,0x50,0x00,0x0f,0x12,0x20,0x01,0x50,0x02,0x40,0x20,0x21,0x02,0x71,0x10,0x21,
-0x00,0x50,0x10,0x2a,0x14,0x40,0x00,0xed,0x02,0x92,0x10,0x21,0x93,0x82,0x8b,0x71,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0xe0,0x02,0x92,0x28,0x21,
-0x26,0xe2,0x00,0x01,0x30,0x57,0xff,0xff,0x02,0x40,0xf0,0x21,0x26,0xb5,0xff,0xff,
-0x16,0xa0,0xff,0xbd,0x02,0xc0,0x90,0x21,0x16,0xe0,0x00,0xd0,0x00,0x00,0x00,0x00,
-0x8f,0xa3,0x00,0x98,0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x10,0x10,0x40,0x00,0x2e,
-0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x24,0x00,0x00,0x00,0x00,0x18,0x80,0x00,0x2a,
-0x24,0x03,0x00,0x01,0x8f,0xa5,0x00,0x1c,0x27,0x84,0x90,0x04,0x94,0xb2,0x00,0x14,
-0xa0,0xa3,0x00,0x12,0x8f,0xa6,0x00,0x3c,0x00,0x12,0x10,0xc0,0x00,0x52,0x10,0x21,
-0x00,0x02,0x80,0x80,0x27,0x82,0x90,0x10,0x02,0x02,0x10,0x21,0x80,0x43,0x00,0x06,
-0x02,0x04,0x20,0x21,0x8c,0x85,0x00,0x18,0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2,
-0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40,0x14,0xc0,0x00,0x0e,
-0x00,0xa3,0x38,0x21,0x27,0x82,0x90,0x00,0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06,
-0x8f,0xa8,0x00,0x1c,0x24,0x02,0x00,0x01,0xa5,0x03,0x00,0x1a,0x7b,0xbe,0x04,0x3c,
-0x7b,0xb6,0x03,0xfc,0x7b,0xb4,0x03,0xbc,0x7b,0xb2,0x03,0x7c,0x7b,0xb0,0x03,0x3c,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x88,0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38,
-0x8f,0xa6,0x00,0x34,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x0a,0xaf,0xa0,0x00,0x14,
-0x08,0x00,0x1d,0x2d,0x00,0x00,0x00,0x00,0x8f,0xa3,0x00,0x44,0x93,0x82,0x81,0x58,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x61,0x30,0x69,0x00,0x03,0x8f,0xa4,0x00,0x24,
-0x8f,0xa5,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x85,0x10,0x2a,0x10,0x40,0x00,0x8f,
-0x00,0x00,0x00,0x00,0x8f,0xa6,0x00,0x1c,0x00,0x00,0x00,0x00,0x90,0xc4,0x00,0x04,
-0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x00,0xa3,0x10,0x2a,0x10,0x40,0x00,0x87,
-0x00,0x00,0x00,0x00,0x8f,0xa8,0x00,0x24,0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x83,
-0x00,0x65,0x10,0x23,0x00,0xa8,0x18,0x23,0x00,0x62,0x10,0x2a,0x14,0x40,0x00,0x7d,
-0x30,0x63,0x00,0xff,0x00,0x85,0x10,0x23,0x30,0x42,0x00,0xff,0xaf,0xa2,0x00,0x50,
-0x8f,0xa2,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x73,0x00,0x00,0xa8,0x21,
-0x27,0x8c,0x90,0x00,0x3c,0x0b,0x80,0xff,0x24,0x10,0x00,0x04,0x27,0x91,0x90,0x04,
-0x35,0x6b,0xff,0xff,0x3c,0x0d,0x7f,0x00,0x27,0x8e,0x90,0x10,0x01,0x80,0x78,0x21,
-0x00,0x12,0x30,0xc0,0x00,0xd2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4c,0x10,0x21,
-0x94,0x42,0x00,0x06,0x8f,0xa3,0x00,0x2c,0x8f,0xa4,0x00,0x30,0xaf,0xa2,0x00,0x44,
-0x8f,0xa5,0x00,0x44,0x30,0x49,0x00,0x03,0x02,0x09,0x10,0x23,0x30,0x42,0x00,0x03,
-0x00,0xa2,0x10,0x21,0x8f,0xa8,0x00,0x30,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff,
-0x00,0x64,0x38,0x21,0x01,0x02,0x28,0x23,0x00,0x62,0x18,0x21,0x00,0x48,0x10,0x2b,
-0x10,0x40,0x00,0x52,0x00,0x00,0x20,0x21,0x30,0xe7,0xff,0xff,0x30,0xa4,0xff,0xff,
-0xaf,0xa7,0x00,0x2c,0x00,0xd2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x51,0x18,0x21,
-0x8c,0x65,0x00,0x18,0x00,0x04,0x25,0x40,0x00,0x8d,0x20,0x24,0x8c,0xa8,0x00,0x04,
-0x00,0x4e,0x18,0x21,0x00,0x4f,0x50,0x21,0x01,0x0b,0x40,0x24,0x01,0x04,0x40,0x25,
-0xac,0xa8,0x00,0x04,0x8f,0xa4,0x00,0x98,0x8f,0xa2,0x00,0x50,0x26,0xb5,0x00,0x01,
-0xa0,0x64,0x00,0x00,0x8c,0xa4,0x00,0x08,0x00,0x00,0x00,0x00,0x04,0x81,0x00,0x0c,
-0x02,0xa2,0x30,0x2a,0x80,0x62,0x00,0x06,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,
-0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,
-0x00,0xa2,0x38,0x21,0x8f,0xa5,0x00,0x40,0x00,0x00,0x00,0x00,0xa4,0xe5,0x00,0x00,
-0x95,0x52,0x00,0x02,0x14,0xc0,0xff,0xc7,0x00,0x12,0x30,0xc0,0x8f,0xa4,0x00,0x24,
-0x8f,0xa5,0x00,0x50,0x8f,0xa6,0x00,0x1c,0x8f,0xa3,0x00,0x2c,0x00,0x85,0x80,0x21,
-0xa0,0xd0,0x00,0x12,0x00,0x09,0x10,0x23,0x30,0x42,0x00,0x03,0x8f,0xa8,0x00,0x88,
-0x00,0x62,0x10,0x23,0xa4,0xc2,0x00,0x1a,0x85,0x03,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x04,
-0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,
-0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x14,0x60,0xff,0x74,0x02,0x00,0x10,0x21,
-0x8f,0xa3,0x00,0x54,0x8f,0xa4,0x00,0x18,0x8f,0xa5,0x00,0x24,0x00,0x64,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x18,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,
-0x10,0xa0,0x00,0x03,0x00,0x00,0x30,0x21,0x08,0x00,0x1d,0x33,0x02,0x00,0x10,0x21,
-0x93,0x82,0x80,0x10,0x00,0x00,0x28,0x21,0x00,0x00,0x38,0x21,0x0c,0x00,0x21,0x9a,
-0xaf,0xa2,0x00,0x10,0x08,0x00,0x1d,0x33,0x02,0x00,0x10,0x21,0x30,0x63,0xff,0xff,
-0x08,0x00,0x1d,0x85,0xaf,0xa3,0x00,0x2c,0x8f,0xa8,0x00,0x44,0x08,0x00,0x1d,0xa7,
-0x31,0x09,0x00,0x03,0x08,0x00,0x1d,0x60,0xaf,0xa3,0x00,0x50,0x8f,0xa6,0x00,0x44,
-0xaf,0xa0,0x00,0x50,0x08,0x00,0x1d,0xa7,0x30,0xc9,0x00,0x03,0x8f,0xa5,0x00,0x48,
-0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c,0x03,0xc0,0x38,0x21,0x0c,0x00,0x1b,0xd8,
-0xaf,0xb7,0x00,0x10,0x08,0x00,0x1d,0x10,0x00,0x00,0x00,0x00,0x00,0x05,0x28,0x80,
-0x27,0x82,0x90,0x00,0x00,0xa2,0x28,0x21,0x00,0x00,0x20,0x21,0x0c,0x00,0x01,0x49,
-0x00,0x00,0x00,0x00,0x08,0x00,0x1d,0x09,0x26,0xe2,0x00,0x01,0x00,0x02,0x80,0x80,
-0x27,0x83,0x90,0x10,0x8f,0xa4,0x00,0x1c,0x02,0x03,0x18,0x21,0x26,0x31,0x00,0x01,
-0x02,0x40,0x28,0x21,0x0c,0x00,0x1e,0xea,0xa0,0x71,0x00,0x05,0x14,0x40,0xff,0x13,
-0x00,0x00,0x00,0x00,0x16,0xe0,0x00,0x4d,0x03,0xc0,0x38,0x21,0x8f,0xa4,0x00,0x24,
-0x8f,0xa5,0x00,0x20,0x24,0x02,0x00,0x01,0x24,0x84,0x00,0x01,0xaf,0xb2,0x00,0x48,
-0xaf,0xb6,0x00,0x4c,0x02,0xc0,0xf0,0x21,0x10,0xa2,0x00,0x41,0xaf,0xa4,0x00,0x24,
-0x27,0x82,0x90,0x00,0x02,0x02,0x10,0x21,0x94,0x42,0x00,0x06,0x8f,0xa4,0x00,0x30,
-0xaf,0xa0,0x00,0x20,0xaf,0xa2,0x00,0x44,0x30,0x49,0x00,0x03,0x8f,0xa8,0x00,0x44,
-0x00,0x09,0x10,0x23,0x30,0x42,0x00,0x03,0x01,0x02,0x10,0x21,0x24,0x42,0x00,0x04,
-0x30,0x42,0xff,0xff,0x00,0x44,0x18,0x2b,0x10,0x60,0x00,0x2b,0x00,0x00,0x00,0x00,
-0x8f,0xa5,0x00,0x2c,0x00,0x82,0x10,0x23,0x00,0xa4,0x18,0x21,0x30,0x63,0xff,0xff,
-0x30,0x44,0xff,0xff,0xaf,0xa3,0x00,0x2c,0x02,0x92,0x28,0x21,0x00,0x05,0x28,0x80,
-0x27,0x82,0x90,0x04,0x00,0xa2,0x10,0x21,0x8c,0x46,0x00,0x18,0x3c,0x03,0x80,0xff,
-0x3c,0x02,0x7f,0x00,0x8c,0xc8,0x00,0x04,0x00,0x04,0x25,0x40,0x34,0x63,0xff,0xff,
-0x00,0x82,0x20,0x24,0x01,0x03,0x40,0x24,0x01,0x04,0x40,0x25,0xac,0xc8,0x00,0x04,
-0x8f,0xa8,0x00,0x98,0x27,0x82,0x90,0x10,0x00,0xa2,0x10,0x21,0xa0,0x48,0x00,0x00,
-0x8c,0xc4,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x27,0xc2,0x10,0x80,0xfe,0xdb,
-0xaf,0xa4,0x00,0x3c,0x80,0x42,0x00,0x06,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,
-0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,
-0x00,0xc2,0x38,0x21,0x8f,0xa2,0x00,0x40,0x00,0x00,0x00,0x00,0xa4,0xe2,0x00,0x00,
-0x08,0x00,0x1d,0x0c,0x26,0xb5,0xff,0xff,0x8f,0xa6,0x00,0x2c,0x00,0x00,0x20,0x21,
-0x00,0xc2,0x10,0x21,0x30,0x42,0xff,0xff,0x08,0x00,0x1e,0x1a,0xaf,0xa2,0x00,0x2c,
-0x8f,0xa6,0x00,0x1c,0x08,0x00,0x1e,0x04,0xa4,0xd2,0x00,0x14,0x8f,0xa5,0x00,0x48,
-0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c,0x0c,0x00,0x1b,0xd8,0xaf,0xb7,0x00,0x10,
-0x08,0x00,0x1d,0xfb,0x00,0x00,0xb8,0x21,0x0c,0x00,0x12,0x8b,0x00,0x00,0x28,0x21,
-0x00,0x40,0x18,0x21,0x94,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x42,0x08,0x00,
-0xa4,0x62,0x00,0x00,0x08,0x00,0x1d,0x00,0x02,0x71,0x10,0x21,0x02,0x92,0x18,0x21,
-0x00,0x03,0x80,0x80,0x27,0x82,0x90,0x04,0x02,0x02,0x10,0x21,0x8c,0x44,0x00,0x18,
-0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,
-0x10,0x60,0x00,0x09,0x24,0x06,0x00,0x01,0x93,0x82,0x8b,0x71,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x01,0x10,0x40,0xfe,0xa2,0x3c,0x04,0x00,0x80,0x27,0x85,0x90,0x00,
-0x08,0x00,0x1d,0xeb,0x02,0x05,0x28,0x21,0x27,0x83,0x90,0x18,0x27,0x82,0x90,0x10,
-0x02,0x03,0x18,0x21,0x02,0x02,0x10,0x21,0x90,0x64,0x00,0x00,0x90,0x45,0x00,0x05,
-0x93,0x83,0x80,0x10,0x00,0x00,0x38,0x21,0x0c,0x00,0x21,0x9a,0xaf,0xa3,0x00,0x10,
-0x08,0x00,0x1e,0x62,0x00,0x00,0x00,0x00,0x27,0x82,0x90,0x18,0x02,0x02,0x10,0x21,
-0x94,0x43,0x00,0x02,0x8f,0xa6,0x00,0x58,0x00,0x03,0x19,0x02,0x00,0x66,0x18,0x23,
-0x30,0x63,0x0f,0xff,0x28,0x62,0x00,0x20,0x10,0x40,0x00,0x06,0x28,0x62,0x00,0x40,
-0x8f,0xa8,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x68,0x10,0x06,0x08,0x00,0x1c,0xd9,
-0x30,0x44,0x00,0x01,0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x94,
-0x08,0x00,0x1e,0x83,0x00,0x64,0x10,0x06,0x08,0x00,0x1c,0xd9,0x00,0x00,0x20,0x21,
-0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x0a,
-0xaf,0xa8,0x00,0x14,0x30,0x42,0xff,0xff,0x08,0x00,0x1c,0xa9,0xaf,0xa2,0x00,0x40,
-0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x27,0xbd,0xff,0xe0,0x34,0x42,0x00,0x20,
-0x24,0x63,0x7a,0x50,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18,
-0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x0a,0x00,0x80,0x80,0x21,0x14,0x40,0x00,0x45,
-0x00,0x00,0x88,0x21,0x92,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x3c,
-0x00,0x00,0x00,0x00,0x12,0x20,0x00,0x18,0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,
-0x92,0x05,0x00,0x0a,0x30,0x42,0x00,0xfc,0x10,0xa0,0x00,0x03,0xa2,0x02,0x00,0x16,
-0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,0x92,0x04,0x00,0x04,0x00,0x00,0x00,0x00,
-0x30,0x83,0x00,0xff,0x10,0x60,0x00,0x05,0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,
-0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,0xa2,0x02,0x00,0x16,0x10,0x60,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x14,0xa0,0x00,0x08,0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x00,
-0xa2,0x00,0x00,0x17,0xa6,0x02,0x00,0x14,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x14,0x80,0x00,0x05,0x24,0x02,0x00,0x01,
-0x96,0x03,0x00,0x06,0xa2,0x02,0x00,0x17,0x08,0x00,0x1e,0xbe,0xa6,0x03,0x00,0x14,
-0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,0x27,0x86,0x90,0x00,0x00,0x04,0x10,0xc0,
-0x00,0x05,0x18,0xc0,0x00,0x44,0x10,0x21,0x00,0x65,0x18,0x21,0x00,0x02,0x10,0x80,
-0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,
-0x8c,0x44,0x00,0x08,0x0c,0x00,0x12,0x7c,0x00,0x00,0x00,0x00,0x30,0x43,0x00,0xff,
-0x10,0x60,0x00,0x04,0xa2,0x02,0x00,0x17,0x96,0x02,0x00,0x06,0x08,0x00,0x1e,0xbe,
-0xa6,0x02,0x00,0x14,0x96,0x02,0x00,0x00,0x08,0x00,0x1e,0xbe,0xa6,0x02,0x00,0x14,
-0x96,0x05,0x00,0x00,0x0c,0x00,0x1e,0xea,0x02,0x00,0x20,0x21,0x08,0x00,0x1e,0xa5,
-0x02,0x22,0x88,0x21,0x94,0x85,0x00,0x06,0x0c,0x00,0x1e,0xea,0x00,0x00,0x00,0x00,
-0x08,0x00,0x1e,0xa1,0x00,0x40,0x88,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x34,0x63,0x00,0x20,0x24,0x42,0x7b,0xa8,0x27,0xbd,0xff,0xf0,0xac,0x62,0x00,0x00,
-0x00,0x00,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x10,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x7b,0xcc,0xac,0x62,0x00,0x00,
-0x90,0x89,0x00,0x0a,0x00,0x80,0x30,0x21,0x11,0x20,0x00,0x05,0x00,0xa0,0x50,0x21,
-0x90,0x82,0x00,0x17,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1b,0x00,0x00,0x00,0x00,
-0x90,0xc7,0x00,0x04,0x00,0x00,0x00,0x00,0x10,0xe0,0x00,0x1b,0x00,0x00,0x00,0x00,
-0x94,0xc8,0x00,0x00,0x27,0x83,0x90,0x00,0x93,0x85,0x8b,0x70,0x00,0x08,0x10,0xc0,
-0x00,0x48,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x08,
-0x00,0xe5,0x28,0x2b,0x10,0xa0,0x00,0x06,0x01,0x44,0x18,0x23,0x8f,0x82,0x8b,0x88,
-0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,
-0x24,0x03,0x00,0x10,0xa4,0xc8,0x00,0x14,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,
-0x11,0x20,0x00,0x05,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x06,0x24,0x03,0x00,0x08,
-0x08,0x00,0x1f,0x16,0xa4,0xc2,0x00,0x14,0x08,0x00,0x1f,0x16,0x00,0x00,0x18,0x21,
-0x27,0xbd,0xff,0xc8,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24,
-0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x30,0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,
-0x94,0x91,0x00,0x06,0x00,0x80,0xa0,0x21,0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03,
-0x00,0x11,0xa8,0xc0,0x34,0x84,0x00,0x20,0x24,0x42,0x7c,0x80,0x02,0xb1,0x48,0x21,
-0xac,0x82,0x00,0x00,0x00,0x09,0x48,0x80,0x24,0x03,0x00,0x01,0x27,0x82,0x90,0x10,
-0xa2,0x83,0x00,0x12,0x01,0x22,0x10,0x21,0x27,0x84,0x90,0x04,0x01,0x24,0x20,0x21,
-0x80,0x48,0x00,0x06,0x8c,0x8a,0x00,0x18,0x27,0x83,0x90,0x20,0x01,0x23,0x48,0x21,
-0x8d,0x24,0x00,0x00,0x25,0x08,0x00,0x02,0x8d,0x42,0x00,0x00,0x8d,0x49,0x00,0x04,
-0x00,0x08,0x17,0xc2,0x8d,0x43,0x00,0x08,0x01,0x02,0x40,0x21,0x00,0x04,0x25,0xc2,
-0x00,0x08,0x40,0x43,0x30,0x84,0x00,0x01,0x00,0x03,0x1f,0xc2,0x00,0x08,0x40,0x40,
-0x00,0xe0,0x80,0x21,0x00,0x64,0x18,0x24,0x00,0x09,0x49,0x42,0x01,0x48,0x10,0x21,
-0x00,0xa0,0x98,0x21,0x00,0xa0,0x20,0x21,0x00,0x40,0x38,0x21,0x02,0x00,0x28,0x21,
-0x14,0x60,0x00,0x19,0x31,0x29,0x00,0x01,0x94,0x42,0x00,0x00,0x02,0xb1,0x88,0x21,
-0x02,0x00,0x28,0x21,0x00,0x11,0x88,0x80,0x27,0x90,0x90,0x00,0x02,0x30,0x80,0x21,
-0x96,0x03,0x00,0x06,0x30,0x52,0xff,0xff,0x02,0x60,0x20,0x21,0x00,0x60,0x30,0x21,
-0xa6,0x83,0x00,0x1a,0x27,0x82,0x90,0x08,0x0c,0x00,0x08,0xe3,0x02,0x22,0x88,0x21,
-0x00,0x52,0x10,0x21,0x96,0x03,0x00,0x06,0xa6,0x22,0x00,0x04,0x8f,0xbf,0x00,0x30,
-0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x00,0x60,0x10,0x21,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0xaf,0xa9,0x00,0x10,0x0c,0x00,0x09,0x0a,
-0xaf,0xa0,0x00,0x14,0x08,0x00,0x1f,0x54,0x02,0xb1,0x88,0x21,0x27,0xbd,0xff,0xc0,
-0xaf,0xbe,0x00,0x38,0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c,
-0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x3c,0xaf,0xb4,0x00,0x28,
-0xaf,0xb2,0x00,0x20,0xaf,0xb0,0x00,0x18,0x94,0x90,0x00,0x00,0x3c,0x08,0xb0,0x03,
-0x35,0x08,0x00,0x20,0x00,0x10,0x10,0xc0,0x00,0x50,0x18,0x21,0x00,0x40,0x88,0x21,
-0x3c,0x02,0x80,0x00,0x00,0x03,0x48,0x80,0x24,0x42,0x7d,0xbc,0x00,0x80,0x98,0x21,
-0x27,0x84,0x90,0x10,0x01,0x24,0x20,0x21,0x93,0xb7,0x00,0x53,0xad,0x02,0x00,0x00,
-0x80,0x83,0x00,0x06,0x27,0x82,0x90,0x04,0x01,0x22,0x10,0x21,0x8c,0x44,0x00,0x18,
-0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2,0x8c,0x88,0x00,0x08,0x00,0x62,0x18,0x21,
-0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40,0xaf,0xa7,0x00,0x4c,0x2c,0xa2,0x00,0x10,
-0x00,0xa0,0xa8,0x21,0x00,0x83,0x50,0x21,0x00,0x08,0x47,0xc2,0x00,0xc0,0x58,0x21,
-0x00,0x00,0xb0,0x21,0x8c,0x92,0x00,0x0c,0x14,0x40,0x00,0x13,0x00,0x00,0xf0,0x21,
-0x92,0x67,0x00,0x04,0x24,0x14,0x00,0x01,0x12,0x87,0x00,0x10,0x02,0x30,0x10,0x21,
-0x27,0x83,0x90,0x18,0x01,0x23,0x18,0x21,0x80,0x64,0x00,0x00,0x27,0x83,0xb5,0x70,
-0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x04,0x00,0x00,0x00,0x00,
-0x10,0x80,0x00,0x23,0x00,0x00,0x00,0x00,0x02,0x30,0x10,0x21,0x00,0x02,0x80,0x80,
-0x24,0x04,0x00,0x01,0x27,0x83,0x90,0x20,0xa2,0x64,0x00,0x12,0x02,0x03,0x18,0x21,
-0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01,
-0x01,0x02,0x10,0x24,0x14,0x40,0x00,0x0e,0x02,0xa0,0x20,0x21,0x27,0x82,0x90,0x00,
-0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x63,0x00,0x1a,
-0x94,0x42,0x00,0x06,0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,
-0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,
-0x8f,0xa5,0x00,0x4c,0x01,0x60,0x30,0x21,0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10,
-0x0c,0x00,0x09,0x0a,0xaf,0xa0,0x00,0x14,0x08,0x00,0x1f,0xbb,0x00,0x00,0x00,0x00,
-0x27,0x83,0x90,0x20,0x01,0x23,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24,0x14,0x40,0x00,0xaf,
-0x00,0xa0,0x20,0x21,0x32,0x4f,0x00,0x03,0x00,0x12,0x10,0x82,0x25,0xe3,0x00,0x0d,
-0x30,0x45,0x00,0x07,0x00,0x74,0x78,0x04,0x10,0xa0,0x00,0x0e,0x00,0x00,0x90,0x21,
-0x27,0x82,0x80,0x1c,0x00,0x15,0x18,0x40,0x00,0x62,0x18,0x21,0x94,0x64,0x00,0x00,
-0x24,0xa2,0x00,0x06,0x00,0x54,0x10,0x04,0x00,0x44,0x00,0x1a,0x14,0x80,0x00,0x02,
-0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,0x00,0x00,0x10,0x12,0x24,0x42,0x00,0x20,
-0x30,0x52,0xff,0xfc,0x02,0x30,0x10,0x21,0x27,0x83,0x90,0x10,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x03,0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,
-0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x04,0x2c,0x62,0x00,0x19,0x30,0x82,0x00,0x0f,
-0x24,0x43,0x00,0x0c,0x2c,0x62,0x00,0x19,0x10,0x40,0x00,0x19,0x24,0x0e,0x00,0x20,
-0x24,0x62,0xff,0xe9,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x15,0x24,0x0e,0x00,0x10,
-0x24,0x62,0xff,0xeb,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x11,0x24,0x0e,0x00,0x08,
-0x24,0x02,0x00,0x14,0x10,0x62,0x00,0x0e,0x24,0x0e,0x00,0x02,0x24,0x62,0xff,0xef,
-0x2c,0x42,0x00,0x03,0x14,0x40,0x00,0x0a,0x24,0x0e,0x00,0x10,0x24,0x62,0xff,0xf1,
-0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x06,0x24,0x0e,0x00,0x08,0x24,0x62,0xff,0xf3,
-0x2c,0x42,0x00,0x02,0x24,0x0e,0x00,0x04,0x24,0x03,0x00,0x02,0x00,0x62,0x70,0x0a,
-0x30,0xe2,0x00,0xff,0x00,0x00,0x48,0x21,0x00,0x00,0x68,0x21,0x10,0x40,0x00,0x6d,
-0x00,0x00,0x58,0x21,0x3c,0x14,0x80,0xff,0x27,0x99,0x90,0x00,0x01,0xf2,0xc0,0x23,
-0x36,0x94,0xff,0xff,0x01,0xc9,0x10,0x2a,0x14,0x40,0x00,0x64,0x24,0x03,0x00,0x04,
-0x00,0x10,0x28,0xc0,0x00,0xb0,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x59,0x10,0x21,
-0x94,0x56,0x00,0x06,0x00,0x00,0x00,0x00,0x32,0xcc,0x00,0x03,0x00,0x6c,0x10,0x23,
-0x30,0x42,0x00,0x03,0x02,0xc2,0x10,0x21,0x24,0x42,0x00,0x04,0x30,0x51,0xff,0xff,
-0x02,0x32,0x18,0x2b,0x10,0x60,0x00,0x4d,0x01,0xf1,0x10,0x23,0x02,0x51,0x10,0x23,
-0x01,0x78,0x18,0x2b,0x10,0x60,0x00,0x34,0x30,0x44,0xff,0xff,0x29,0x22,0x00,0x40,
-0x10,0x40,0x00,0x31,0x01,0x72,0x18,0x21,0x25,0x22,0x00,0x01,0x00,0x02,0x16,0x00,
-0x00,0x02,0x4e,0x03,0x00,0xb0,0x10,0x21,0x00,0x02,0x30,0x80,0x27,0x82,0x90,0x04,
-0x30,0x6b,0xff,0xff,0x00,0xc2,0x18,0x21,0x8c,0x67,0x00,0x18,0x00,0x04,0x25,0x40,
-0x3c,0x03,0x7f,0x00,0x8c,0xe2,0x00,0x04,0x00,0x83,0x20,0x24,0x27,0x83,0x90,0x10,
-0x00,0x54,0x10,0x24,0x00,0xc3,0x28,0x21,0x00,0x44,0x10,0x25,0xac,0xe2,0x00,0x04,
-0x16,0xe0,0x00,0x02,0xa0,0xb5,0x00,0x00,0xa0,0xb5,0x00,0x03,0x27,0x84,0x90,0x20,
-0x00,0xc4,0x18,0x21,0x8c,0x62,0x00,0x00,0x8c,0xe8,0x00,0x08,0x00,0x02,0x15,0xc2,
-0x00,0x08,0x47,0xc2,0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24,0x10,0x40,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x80,0xa2,0x00,0x06,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,
-0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,
-0x00,0xe2,0x50,0x21,0xa5,0x5e,0x00,0x00,0x92,0x62,0x00,0x04,0x25,0xad,0x00,0x01,
-0x27,0x84,0x90,0x00,0x00,0xc4,0x18,0x21,0x01,0xa2,0x10,0x2a,0x94,0x70,0x00,0x02,
-0x14,0x40,0xff,0xb8,0x00,0x00,0x00,0x00,0x96,0x63,0x00,0x14,0x00,0x0c,0x10,0x23,
-0xa2,0x69,0x00,0x12,0x30,0x42,0x00,0x03,0x01,0x62,0x10,0x23,0x00,0x03,0x80,0xc0,
-0x8f,0xa5,0x00,0x4c,0x30,0x4b,0xff,0xff,0x02,0x03,0x80,0x21,0x27,0x82,0x90,0x08,
-0x00,0x10,0x80,0x80,0xa6,0x6b,0x00,0x1a,0x02,0xa0,0x20,0x21,0x01,0x60,0x30,0x21,
-0x01,0x60,0x88,0x21,0x0c,0x00,0x08,0xe3,0x02,0x02,0x80,0x21,0x00,0x5e,0x10,0x21,
-0xa6,0x02,0x00,0x04,0x08,0x00,0x1f,0xc1,0x02,0x20,0x10,0x21,0x01,0x62,0x10,0x2b,
-0x10,0x40,0xff,0xe9,0x00,0x00,0x20,0x21,0x29,0x22,0x00,0x40,0x10,0x40,0xff,0xe6,
-0x01,0x71,0x18,0x21,0x08,0x00,0x20,0x37,0x25,0x22,0x00,0x01,0x08,0x00,0x20,0x66,
-0x32,0xcc,0x00,0x03,0x08,0x00,0x20,0x66,0x00,0x00,0x60,0x21,0x8f,0xa5,0x00,0x4c,
-0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x0a,0xaf,0xb4,0x00,0x14,
-0x92,0x67,0x00,0x04,0x08,0x00,0x1f,0xd9,0x30,0x5e,0xff,0xff,0x30,0x84,0xff,0xff,
-0x00,0x04,0x30,0xc0,0x00,0xc4,0x20,0x21,0x00,0x04,0x20,0x80,0x27,0x82,0x90,0x00,
-0x3c,0x03,0xb0,0x08,0x30,0xa5,0xff,0xff,0x00,0x82,0x20,0x21,0x00,0xc3,0x30,0x21,
-0xac,0xc5,0x00,0x00,0x03,0xe0,0x00,0x08,0xa4,0x85,0x00,0x00,0x30,0x84,0xff,0xff,
-0x00,0x04,0x30,0xc0,0x00,0xc4,0x30,0x21,0x27,0x88,0x90,0x00,0x00,0x06,0x30,0x80,
-0x00,0xc8,0x30,0x21,0x94,0xc3,0x00,0x04,0x3c,0x02,0xb0,0x08,0x3c,0x07,0xb0,0x03,
-0x00,0x03,0x20,0xc0,0x00,0x83,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x82,0x20,0x21,
-0x3c,0x02,0x80,0x01,0x30,0xa5,0xff,0xff,0x00,0x68,0x18,0x21,0x34,0xe7,0x00,0x20,
-0x24,0x42,0x82,0x6c,0xac,0xe2,0x00,0x00,0xa4,0xc5,0x00,0x02,0xa4,0x65,0x00,0x00,
-0x03,0xe0,0x00,0x08,0xac,0x85,0x00,0x00,0x30,0x84,0xff,0xff,0x00,0x04,0x10,0xc0,
-0x00,0x44,0x10,0x21,0x27,0x89,0x90,0x00,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x21,
-0x97,0x83,0x8f,0xf0,0x94,0x4a,0x00,0x04,0x3c,0x02,0xb0,0x08,0x00,0x03,0x38,0xc0,
-0x00,0x0a,0x40,0xc0,0x00,0xe3,0x18,0x21,0x01,0x0a,0x28,0x21,0x00,0xe2,0x38,0x21,
-0x01,0x02,0x40,0x21,0x00,0x03,0x18,0x80,0x00,0x05,0x28,0x80,0x3c,0x06,0xb0,0x03,
-0x3c,0x02,0x80,0x01,0x00,0xa9,0x28,0x21,0x00,0x69,0x18,0x21,0x34,0xc6,0x00,0x20,
-0x34,0x09,0xff,0xff,0x24,0x42,0x82,0xc8,0xac,0xc2,0x00,0x00,0xa4,0x64,0x00,0x00,
-0xac,0xe4,0x00,0x00,0xa4,0xa9,0x00,0x00,0xad,0x09,0x00,0x00,0xa7,0x8a,0x8f,0xf0,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,
-0x34,0x63,0x00,0x20,0x24,0x42,0x83,0x48,0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,
-0x34,0x84,0x01,0x10,0x8c,0x82,0x00,0x00,0x97,0x83,0x81,0x60,0x30,0x42,0xff,0xff,
-0x10,0x62,0x00,0x16,0x24,0x0a,0x00,0x01,0xa7,0x82,0x81,0x60,0xaf,0x80,0xb4,0x50,
-0x00,0x40,0x28,0x21,0x24,0x06,0x00,0x01,0x27,0x84,0xb4,0x54,0x25,0x43,0xff,0xff,
-0x00,0x66,0x10,0x04,0x00,0xa2,0x10,0x24,0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,
-0x8c,0x83,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x66,0x10,0x04,0x00,0xa2,0x10,0x24,
-0x38,0x42,0x00,0x00,0x01,0x42,0x18,0x0a,0x25,0x4a,0x00,0x01,0x2d,0x42,0x00,0x14,
-0xac,0x83,0x00,0x00,0x14,0x40,0xff,0xf1,0x24,0x84,0x00,0x04,0x3c,0x0b,0xb0,0x03,
-0x00,0x00,0x50,0x21,0x3c,0x0c,0x80,0x00,0x27,0x89,0xb4,0xa0,0x35,0x6b,0x01,0x20,
-0x8d,0x68,0x00,0x00,0x8d,0x23,0x00,0x04,0x01,0x0c,0x10,0x24,0x00,0x02,0x17,0xc2,
-0x11,0x03,0x00,0x37,0xa1,0x22,0x00,0xdc,0xa1,0x20,0x00,0xd5,0xa1,0x20,0x00,0xd6,
-0x01,0x20,0x30,0x21,0x00,0x00,0x38,0x21,0x00,0x00,0x28,0x21,0x01,0x20,0x20,0x21,
-0x00,0xa8,0x10,0x06,0x30,0x42,0x00,0x01,0x10,0xe0,0x00,0x10,0xa0,0x82,0x00,0x0a,
-0x90,0x82,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x31,0x24,0xa2,0xff,0xff,
-0xa0,0x82,0x00,0x08,0x90,0x82,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x09,
-0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x40,
-0x00,0x43,0x10,0x21,0x00,0x46,0x10,0x21,0xa0,0x45,0x00,0x09,0x90,0x82,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x04,
-0x00,0x00,0x00,0x00,0xa0,0xc5,0x00,0xd5,0x24,0x07,0x00,0x01,0xa0,0x85,0x00,0x08,
-0xa0,0xc5,0x00,0xd6,0x24,0xa5,0x00,0x01,0x2c,0xa2,0x00,0x1c,0x14,0x40,0xff,0xe0,
-0x24,0x84,0x00,0x03,0x90,0xc4,0x00,0xd5,0x00,0x00,0x28,0x21,0x00,0xa4,0x10,0x2b,
-0x10,0x40,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0xc0,0x18,0x21,0xa0,0x64,0x00,0x08,
-0x90,0xc2,0x00,0xd5,0x24,0xa5,0x00,0x01,0xa0,0x62,0x00,0x09,0x90,0xc4,0x00,0xd5,
-0x00,0x00,0x00,0x00,0x00,0xa4,0x10,0x2b,0x14,0x40,0xff,0xf8,0x24,0x63,0x00,0x03,
-0x25,0x4a,0x00,0x01,0x2d,0x42,0x00,0x08,0xad,0x28,0x00,0x04,0x25,0x6b,0x00,0x04,
-0x14,0x40,0xff,0xbf,0x25,0x29,0x00,0xec,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x90,0x82,0x00,0x05,0x08,0x00,0x21,0x0d,0xa0,0x82,0x00,0x08,0x97,0x85,0x8b,0x7a,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x63,0x00,0x20,
-0x24,0x42,0x84,0xfc,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x62,0x00,0x00,
-0x30,0x90,0x00,0xff,0x00,0x05,0x28,0x42,0x00,0x00,0x48,0x21,0x27,0x8f,0xb4,0xa4,
-0x00,0x00,0x50,0x21,0x00,0x00,0x58,0x21,0x27,0x98,0xb5,0x84,0x27,0x99,0xb5,0x80,
-0x27,0x8e,0xb5,0x7e,0x27,0x8c,0xb4,0xa8,0x27,0x8d,0xb5,0x00,0x27,0x88,0xb5,0x78,
-0x00,0x0a,0x18,0x80,0x01,0x6f,0x10,0x21,0xac,0x40,0x00,0x00,0xac,0x45,0x00,0x58,
-0x00,0x6e,0x20,0x21,0x00,0x78,0x10,0x21,0xa1,0x00,0xff,0xfc,0xad,0x00,0x00,0x00,
-0xa1,0x00,0x00,0x04,0xa1,0x00,0x00,0x05,0xad,0x00,0xff,0xf8,0x00,0x79,0x18,0x21,
-0x24,0x06,0x00,0x01,0x24,0xc6,0xff,0xff,0xa0,0x80,0x00,0x00,0xa4,0x60,0x00,0x00,
-0xac,0x40,0x00,0x00,0x24,0x63,0x00,0x02,0x24,0x42,0x00,0x04,0x04,0xc1,0xff,0xf9,
-0x24,0x84,0x00,0x01,0x00,0x0a,0x10,0x80,0x00,0x4d,0x20,0x21,0x00,0x00,0x30,0x21,
-0x00,0x4c,0x18,0x21,0x27,0x87,0x81,0x64,0x8c,0xe2,0x00,0x00,0x24,0xe7,0x00,0x04,
-0xac,0x82,0x00,0x00,0xa0,0x66,0x00,0x00,0xa0,0x66,0x00,0x01,0x24,0xc6,0x00,0x01,
-0x28,0xc2,0x00,0x1c,0xa0,0x60,0x00,0x02,0x24,0x84,0x00,0x04,0x14,0x40,0xff,0xf6,
-0x24,0x63,0x00,0x03,0x25,0x29,0x00,0x01,0x29,0x22,0x00,0x08,0x25,0x4a,0x00,0x3b,
-0x25,0x08,0x00,0xec,0x14,0x40,0xff,0xd6,0x25,0x6b,0x00,0xec,0xa7,0x80,0x81,0x60,
-0x00,0x00,0x48,0x21,0x27,0x83,0xb4,0x50,0xac,0x69,0x00,0x00,0x25,0x29,0x00,0x01,
-0x29,0x22,0x00,0x0c,0x14,0x40,0xff,0xfc,0x24,0x63,0x00,0x04,0x0c,0x00,0x20,0xd2,
-0x00,0x00,0x00,0x00,0x2e,0x04,0x00,0x14,0x27,0x83,0xb4,0xa0,0x24,0x09,0x00,0x07,
-0x10,0x80,0x00,0x0a,0x00,0x00,0x00,0x00,0x90,0x62,0x00,0xd5,0x25,0x29,0xff,0xff,
-0xa0,0x62,0x00,0x00,0x05,0x21,0xff,0xfa,0x24,0x63,0x00,0xec,0x8f,0xbf,0x00,0x14,
-0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x90,0x62,0x00,0xd6,
-0x08,0x00,0x21,0x90,0x25,0x29,0xff,0xff,0x30,0x84,0x00,0xff,0x00,0x04,0x11,0x00,
-0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,
-0x27,0x83,0xb4,0xa0,0x00,0x43,0x60,0x21,0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x01,
-0x34,0x84,0x00,0x20,0x24,0x42,0x86,0x68,0x30,0xc6,0x00,0xff,0x93,0xaa,0x00,0x13,
-0x30,0xa5,0x00,0xff,0x30,0xe7,0x00,0xff,0xac,0x82,0x00,0x00,0x10,0xc0,0x00,0xe8,
-0x25,0x8f,0x00,0xd0,0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xfc,
-0x2c,0x43,0x00,0x18,0x10,0x60,0x00,0xc7,0x3c,0x03,0x80,0x01,0x00,0x02,0x10,0x80,
-0x24,0x63,0x02,0x90,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x30,0x14,0x40,0x00,0x1c,
-0x00,0x00,0x00,0x00,0x10,0xa0,0x00,0x17,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0x10,0xa2,0x00,0x11,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x06,0x00,0x00,0x00,0x00,
-0x8d,0x82,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xe0,0x03,0xe0,0x00,0x08,
-0xad,0x82,0x00,0xd0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xe8,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb,
-0x24,0x42,0x00,0x01,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb,0x24,0x42,0x00,0x02,
-0x10,0xa0,0xff,0xf9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xe9,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xe6,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,
-0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xd0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb,
-0x24,0x42,0xff,0xfc,0x10,0xa0,0xff,0xeb,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0x10,0xa2,0xff,0xe5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xe0,
-0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xdb,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,
-0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xf8,0x2d,0x42,0x00,0x19,0x14,0x40,0xff,0xc5,
-0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xdb,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0x10,0xa2,0xff,0xd5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd0,
-0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,
-0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xf0,0x2d,0x42,0x00,0x1b,0x10,0x40,0xff,0xf1,
-0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xcb,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0x10,0xa2,0xff,0xc5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x14,0xa2,0xff,0xb5,
-0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xf4,
-0x2d,0x42,0x00,0x1e,0x10,0x40,0xff,0xe3,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xbd,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xb5,0x24,0x02,0x00,0x02,
-0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xc6,0x24,0x02,0x00,0x03,
-0x2d,0x42,0x00,0x23,0x10,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xae,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xa9,0x24,0x02,0x00,0x02,
-0x14,0xa2,0xff,0xb7,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x03,0x00,0x00,0x00,0x00,
-0x2d,0x42,0x00,0x25,0x10,0x40,0xff,0xcb,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xd8,
-0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x16,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,
-0x10,0xa0,0xff,0xa0,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x9a,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x95,0x24,0x02,0x00,0x03,
-0x14,0xa2,0xff,0xb6,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb,
-0x24,0x42,0xff,0xfa,0x10,0xa0,0xff,0x93,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0x10,0xa2,0xff,0x8d,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x88,
-0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xf3,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x17,
-0x14,0x40,0xff,0xac,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x34,0x00,0x00,0x00,0x00,
-0x2d,0x42,0x00,0x19,0x10,0x40,0xff,0xe2,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x81,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x7b,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x76,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x97,
-0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xc8,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x51,
-0x2d,0x42,0x00,0x1b,0x2d,0x42,0x00,0x1e,0x10,0x40,0xff,0xde,0x00,0x00,0x00,0x00,
-0x10,0xa0,0xff,0x70,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x6a,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x65,0x24,0x02,0x00,0x03,
-0x10,0xa2,0xff,0x96,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xc8,0x00,0x00,0x00,0x00,
-0x2d,0x42,0x00,0x23,0x14,0x40,0xff,0xf2,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xf9,
-0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xf7,0x2d,0x42,0x00,0x25,0x08,0x00,0x22,0x2d,
-0x2d,0x42,0x00,0x27,0x10,0xa0,0xff,0x5b,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0x10,0xa2,0xff,0x55,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x50,
-0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0x71,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xe6,
-0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x27,0x14,0x40,0xff,0xad,0x00,0x00,0x00,0x00,
-0x08,0x00,0x22,0x79,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2a,0x14,0x40,0xff,0xd8,
-0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xe9,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2c,
-0x14,0x40,0xff,0x78,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xbd,0x00,0x00,0x00,0x00,
-0x91,0x86,0x00,0x00,0x91,0x83,0x00,0xd4,0x25,0x8d,0x00,0x5c,0x30,0xc4,0x00,0xff,
-0x00,0x04,0x10,0x40,0x00,0x44,0x10,0x21,0x00,0x04,0x48,0x80,0x01,0x82,0x58,0x21,
-0x01,0x89,0x40,0x21,0x25,0x78,0x00,0x08,0x10,0x60,0x00,0x37,0x25,0x0e,0x00,0x60,
-0x2c,0xa2,0x00,0x03,0x14,0x40,0x00,0x25,0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1e,0x00,0x00,0x00,0x00,0x27,0x87,0x81,0x64,
-0x01,0x27,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xad,0x03,0x00,0x60,
-0x91,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x40,0x30,0x21,0xa1,0x82,0x00,0x00,
-0x30,0xc2,0x00,0xff,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0x8c,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x03,0x18,0x42,0xad,0xa3,0x00,0x00,0x91,0x84,0x00,0x00,
-0x8d,0xc5,0x00,0x00,0x00,0x04,0x20,0x80,0x00,0x87,0x10,0x21,0x8c,0x43,0x00,0x00,
-0x00,0x05,0x28,0x40,0x00,0x8c,0x20,0x21,0x00,0x03,0x18,0x80,0x00,0xa3,0x10,0x2b,
-0x00,0x62,0x28,0x0a,0xac,0x85,0x00,0x60,0x03,0xe0,0x00,0x08,0xa1,0x80,0x00,0xd4,
-0x27,0x87,0x81,0x64,0x08,0x00,0x22,0xb0,0xa1,0x80,0x00,0xdd,0x27,0x82,0x81,0xd4,
-0x8d,0x83,0x00,0xd8,0x00,0x82,0x10,0x21,0x90,0x44,0x00,0x00,0x24,0x63,0x00,0x01,
-0x00,0x64,0x20,0x2b,0x14,0x80,0xff,0x02,0xad,0x83,0x00,0xd8,0x8d,0x02,0x00,0x60,
-0xa1,0x80,0x00,0xd4,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,
-0x03,0xe0,0x00,0x08,0xad,0x82,0x00,0x5c,0x10,0xe0,0x00,0x1d,0x24,0x83,0xff,0xfc,
-0x2c,0x62,0x00,0x18,0x10,0x40,0x01,0x10,0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01,
-0x24,0x63,0x02,0xf0,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x30,0x14,0x40,0x00,0x65,
-0x00,0x00,0x00,0x00,0x10,0xa0,0x00,0x60,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0x10,0xa2,0x00,0x5a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x08,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x51,0x00,0x00,0x00,0x00,
-0x8d,0x82,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xe0,0xad,0x82,0x00,0xd0,
-0x8d,0xe3,0x00,0x00,0x8d,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,
-0xad,0xa2,0x00,0x00,0xad,0xe0,0x00,0x00,0x8d,0xa3,0x00,0x00,0x8d,0xc4,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x83,0x10,0x2a,0x10,0x40,0x00,0x22,0x00,0x00,0x00,0x00,
-0x93,0x05,0x00,0x01,0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x45,0x00,0x05,
-0x24,0x02,0x00,0x01,0xa1,0x85,0x00,0x00,0xa1,0x82,0x00,0xd4,0x03,0xe0,0x00,0x08,
-0xad,0x80,0x00,0xd8,0x91,0x82,0x00,0xdd,0x24,0x03,0x00,0x01,0x10,0x43,0x00,0x05,
-0x00,0x00,0x00,0x00,0xa1,0x83,0x00,0xd4,0xad,0x80,0x00,0xd8,0x03,0xe0,0x00,0x08,
-0xa1,0x83,0x00,0xdd,0x00,0x04,0x17,0xc2,0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x43,
-0xad,0xa2,0x00,0x00,0x91,0x83,0x00,0x00,0x27,0x82,0x81,0x64,0x8d,0xc5,0x00,0x00,
-0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,0x00,0x05,0x28,0x40,
-0x00,0x04,0x18,0x80,0x00,0xa3,0x10,0x2b,0x00,0x62,0x28,0x0a,0x08,0x00,0x22,0xc2,
-0xad,0xc5,0x00,0x00,0x97,0x82,0x8b,0x7c,0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x2a,
-0x10,0x40,0xfe,0xab,0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x15,0x00,0x00,0x00,0x00,0x91,0x83,0x00,0x00,0x27,0x82,0x81,0x64,
-0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x6c,0x18,0x21,
-0xac,0x64,0x00,0x60,0x93,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x10,0x80,
-0x01,0x82,0x10,0x21,0x24,0x4e,0x00,0x60,0xa1,0x85,0x00,0x00,0x8d,0xc2,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,
-0x03,0xe0,0x00,0x08,0xad,0xa2,0x00,0x00,0x08,0x00,0x23,0x37,0xa1,0x80,0x00,0xdd,
-0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xe8,0x8d,0x82,0x00,0xd0,
-0x08,0x00,0x22,0xf3,0x24,0x42,0x00,0x01,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,
-0x24,0x42,0x00,0x02,0x10,0xa0,0xff,0xf9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0x10,0xa2,0x00,0x0a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xa0,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x9d,0x00,0x00,0x00,0x00,
-0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xd0,0x8d,0x82,0x00,0xd0,
-0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xfc,0x10,0xa0,0xff,0xeb,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xe5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x10,0xa2,0xff,0x93,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xdd,0x00,0x00,0x00,0x00,
-0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xf8,0x2d,0x42,0x00,0x19,
-0x14,0x40,0xff,0x7c,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xdb,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xd5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x10,0xa2,0xff,0x83,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00,
-0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xf0,0x2d,0x42,0x00,0x1b,
-0x10,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xcb,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xc5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x14,0xa2,0xff,0x6c,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,
-0x24,0x42,0xff,0xf4,0x2d,0x42,0x00,0x1e,0x10,0x40,0xff,0xe3,0x00,0x00,0x00,0x00,
-0x10,0xa0,0xff,0xbd,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x68,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xee,
-0x24,0x02,0x00,0x03,0x2d,0x42,0x00,0x23,0x10,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,
-0x10,0xa0,0xff,0xae,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x5c,
-0x24,0x02,0x00,0x02,0x14,0xa2,0xff,0xb7,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x74,
-0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x25,0x10,0x40,0xff,0xcb,0x00,0x00,0x00,0x00,
-0x08,0x00,0x23,0x49,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x16,0x14,0x40,0x00,0x0e,
-0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa0,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0x10,0xa2,0xff,0x9a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x48,
-0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xb6,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,
-0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xfa,0x10,0xa0,0xff,0x93,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x8d,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x10,0xa2,0xff,0x3b,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x64,0x00,0x00,0x00,0x00,
-0x2d,0x42,0x00,0x17,0x14,0x40,0xff,0xac,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xa5,
-0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x19,0x10,0x40,0xff,0xe2,0x00,0x00,0x00,0x00,
-0x10,0xa0,0xff,0x81,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x7b,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x29,0x24,0x02,0x00,0x03,
-0x10,0xa2,0xff,0x97,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xf0,0x00,0x00,0x00,0x00,
-0x08,0x00,0x23,0xc2,0x2d,0x42,0x00,0x1b,0x2d,0x42,0x00,0x1e,0x10,0x40,0xff,0xde,
-0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x70,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0x10,0xa2,0xff,0x6a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x18,
-0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x96,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xf0,
-0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x23,0x14,0x40,0xff,0xf2,0x00,0x00,0x00,0x00,
-0x08,0x00,0x23,0x6a,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x68,0x2d,0x42,0x00,0x25,
-0x08,0x00,0x23,0x9e,0x2d,0x42,0x00,0x27,0x10,0xa0,0xff,0x5b,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x55,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x10,0xa2,0xff,0x03,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0x71,0x00,0x00,0x00,0x00,
-0x08,0x00,0x23,0x57,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x27,0x14,0x40,0xff,0xad,
-0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xea,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2a,
-0x14,0x40,0xff,0xd8,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x5a,0x00,0x00,0x00,0x00,
-0x2d,0x42,0x00,0x2c,0x14,0x40,0xff,0x78,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xe5,
-0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe8,0x3c,0x02,0xb0,0x03,0xaf,0xbf,0x00,0x14,
-0xaf,0xb0,0x00,0x10,0x34,0x42,0x01,0x18,0x3c,0x03,0xb0,0x03,0x8c,0x50,0x00,0x00,
-0x34,0x63,0x01,0x2c,0x90,0x62,0x00,0x00,0x32,0x05,0x00,0x01,0xa3,0x82,0x80,0x10,
-0x14,0xa0,0x00,0x14,0x30,0x44,0x00,0xff,0x32,0x02,0x01,0x00,0x14,0x40,0x00,0x09,
-0x00,0x00,0x00,0x00,0x32,0x02,0x08,0x00,0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x01,
-0xa3,0x82,0xbc,0x18,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x0c,0x00,0x05,0x37,0x00,0x00,0x00,0x00,0x26,0x02,0xff,0x00,
-0xa3,0x80,0xbc,0x18,0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,0x08,0x00,0x24,0x16,
-0x32,0x02,0x08,0x00,0x0c,0x00,0x21,0x3f,0x00,0x00,0x00,0x00,0x26,0x02,0xff,0xff,
-0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,0x08,0x00,0x24,0x13,0x32,0x02,0x01,0x00,
-0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0xaf,0xbf,0x00,0x18,
-0x8c,0x43,0x00,0x00,0x3c,0x02,0x00,0x40,0x24,0x07,0x0f,0xff,0x00,0x03,0x33,0x02,
-0x00,0x03,0x2d,0x02,0x00,0x03,0x43,0x02,0x30,0x69,0x0f,0xff,0x00,0x62,0x18,0x24,
-0x30,0xa5,0x00,0x03,0x30,0xc6,0x00,0xff,0x10,0x60,0x00,0x08,0x31,0x08,0x00,0xff,
-0x01,0x00,0x30,0x21,0x0c,0x00,0x24,0xdf,0xaf,0xa9,0x00,0x10,0x8f,0xbf,0x00,0x18,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x25,0x31,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xd4,0x08,0x00,0x24,0x3f,
-0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0,0x3c,0x02,0xb0,0x03,0xaf,0xbe,0x00,0x38,
-0xaf,0xb5,0x00,0x2c,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x3c,
-0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24,
-0xaf,0xb2,0x00,0x20,0x34,0x42,0x00,0x3f,0x90,0x43,0x00,0x00,0x00,0x80,0x80,0x21,
-0x00,0x00,0xf0,0x21,0x00,0x00,0x88,0x21,0x10,0x60,0x00,0x76,0x00,0x00,0xa8,0x21,
-0x3c,0x01,0xb0,0x03,0xa0,0x20,0x00,0x3f,0x00,0x10,0x12,0x02,0x24,0x04,0x06,0x14,
-0x0c,0x00,0x06,0xd1,0x30,0x54,0x00,0x0f,0x24,0x04,0x06,0x14,0x0c,0x00,0x06,0xd1,
-0xaf,0xa2,0x00,0x10,0x3c,0x03,0x00,0xff,0x34,0x63,0xff,0xff,0x32,0x10,0x00,0x7f,
-0x00,0x43,0x10,0x24,0x00,0x10,0x86,0x00,0x02,0x02,0x80,0x25,0x02,0x00,0x28,0x21,
-0x24,0x04,0x06,0x14,0x3c,0x13,0xbf,0xff,0x0c,0x00,0x06,0xbf,0x3c,0x16,0xb0,0x03,
-0x00,0x00,0x90,0x21,0x3c,0x17,0x40,0x00,0x36,0x73,0xff,0xff,0x36,0xd6,0x00,0x3e,
-0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x00,0x00,0x57,0x10,0x25,0x00,0x40,0x28,0x21,
-0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x00,0x00,0x00,0x80,0x21,0x0c,0x00,0x25,0xf9,
-0x00,0x00,0x00,0x00,0x26,0x03,0x00,0x01,0x10,0x40,0x00,0x46,0x30,0x70,0x00,0xff,
-0x12,0x00,0xff,0xfa,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x00,
-0x00,0x53,0x10,0x24,0x00,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x00,
-0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x37,0x00,0x00,0x00,0x00,0x12,0x80,0x00,0x35,
-0x00,0x00,0x00,0x00,0x32,0x31,0x00,0x7f,0x12,0x20,0x00,0x04,0x24,0x03,0x00,0x04,
-0x27,0xc2,0x00,0x01,0x30,0x5e,0x00,0xff,0x02,0xb1,0xa8,0x21,0x12,0x43,0x00,0x2a,
-0x3c,0x03,0xb0,0x03,0x02,0x43,0x10,0x21,0xa0,0x51,0x00,0x34,0x26,0x42,0x00,0x01,
-0x30,0x52,0x00,0xff,0x2e,0x43,0x00,0x05,0x14,0x60,0xff,0xd9,0x00,0x00,0x00,0x00,
-0x8f,0xa5,0x00,0x10,0x0c,0x00,0x06,0xbf,0x24,0x04,0x06,0x14,0x12,0xa0,0x00,0x0e,
-0x3c,0x02,0xb0,0x03,0x13,0xc0,0x00,0x0d,0x34,0x42,0x00,0x3c,0x00,0x15,0x10,0x40,
-0x00,0x55,0x10,0x21,0x00,0x02,0x10,0xc0,0x00,0x55,0x10,0x21,0x00,0x02,0xa8,0x80,
-0x02,0xbe,0x00,0x1b,0x17,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,
-0x00,0x00,0xa8,0x12,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x3c,0x3c,0x03,0xb0,0x03,
-0x3c,0x04,0xb0,0x03,0xa4,0x55,0x00,0x00,0x34,0x63,0x00,0x1c,0x34,0x84,0x00,0x1d,
-0x24,0x02,0x00,0x01,0xa0,0x60,0x00,0x00,0xa0,0x82,0x00,0x00,0x7b,0xbe,0x01,0xfc,
-0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0xa2,0xd1,0x00,0x00,0x08,0x00,0x24,0x98,
-0x26,0x42,0x00,0x01,0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0xfc,0x08,0x00,0x24,0x8d,
-0x00,0x40,0x88,0x21,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x3c,0x3c,0x04,0xb0,0x03,
-0x3c,0x05,0xb0,0x03,0xa4,0x60,0x00,0x00,0x34,0x84,0x00,0x1c,0x34,0xa5,0x00,0x1d,
-0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x01,0xa0,0x82,0x00,0x00,0x08,0x00,0x24,0xb7,
-0xa0,0xa3,0x00,0x00,0x0c,0x00,0x17,0x99,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x8b,
-0x00,0x10,0x12,0x02,0x3c,0x02,0xb0,0x03,0x3c,0x04,0xb0,0x03,0x34,0x42,0x00,0x3c,
-0x34,0x84,0x00,0x14,0x24,0x03,0x00,0x01,0xa4,0x40,0x00,0x00,0x3c,0x01,0xb0,0x03,
-0xa0,0x23,0x00,0x3f,0x08,0x00,0x24,0xb7,0xac,0x90,0x00,0x00,0x27,0xbd,0xff,0xd8,
-0xaf,0xb0,0x00,0x10,0x30,0xd0,0x00,0xff,0x2e,0x02,0x00,0x2e,0xaf,0xb2,0x00,0x18,
-0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0x30,0xb1,0x00,0xff,
-0x14,0x40,0x00,0x06,0x00,0x80,0x90,0x21,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x2e,0x13,0x00,0x10,
-0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa4,0x24,0x06,0x01,0x07,0x12,0x60,0x00,0x38,
-0x02,0x00,0x30,0x21,0x8f,0xa2,0x00,0x38,0x30,0xc3,0x00,0x3f,0x3c,0x04,0xb0,0x09,
-0x00,0x02,0x14,0x00,0x00,0x43,0x30,0x25,0x34,0x84,0x01,0x60,0x90,0x82,0x00,0x00,
-0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x2a,
-0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x24,0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x20,
-0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x19,0x00,0x00,0x00,0x00,0x16,0x60,0xff,0xe2,
-0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x13,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x0d,
-0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x09,0x24,0x02,0x00,0x03,0x16,0x22,0xff,0xda,
-0x00,0x00,0x00,0x00,0x24,0x04,0x08,0x4c,0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5f,
-0x3c,0x06,0x0c,0xb8,0x08,0x00,0x24,0xea,0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x12,
-0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xd0,0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x12,
-0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x12,0x24,0x04,0x08,0x44,0x24,0x04,0x08,0x4c,
-0x0c,0x00,0x13,0x5f,0x24,0x05,0xff,0xff,0x08,0x00,0x25,0x07,0x00,0x00,0x00,0x00,
-0x08,0x00,0x25,0x20,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xe0,0x00,0x00,0x00,0x00,
-0x08,0x00,0x25,0x20,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x20,0x24,0x04,0x08,0x44,
-0x02,0x40,0x20,0x21,0x0c,0x00,0x25,0x71,0x02,0x20,0x28,0x21,0x08,0x00,0x24,0xf5,
-0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xd8,0x2c,0xc2,0x00,0x2e,0xaf,0xb2,0x00,0x18,
-0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,
-0x00,0xc0,0x80,0x21,0x30,0xb1,0x00,0xff,0x00,0x80,0x90,0x21,0x14,0x40,0x00,0x07,
-0x00,0x00,0x18,0x21,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,
-0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x2e,0x13,0x00,0x10,
-0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa4,0x24,0x06,0x01,0x07,0x12,0x60,0x00,0x24,
-0x02,0x00,0x30,0x21,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x30,0xc5,0x00,0x3f,0x0c,0x00,0x25,0xae,
-0x02,0x20,0x20,0x21,0x16,0x60,0x00,0x0a,0x00,0x40,0x80,0x21,0x24,0x02,0x00,0x01,
-0x12,0x22,0x00,0x15,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x0f,0x24,0x02,0x00,0x02,
-0x12,0x22,0x00,0x0b,0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0x25,0x3d,0x02,0x00,0x18,0x21,0x24,0x04,0x08,0x4c,0x24,0x05,0xff,0xff,
-0x0c,0x00,0x13,0x5f,0x3c,0x06,0x0c,0xb8,0x08,0x00,0x25,0x3d,0x02,0x00,0x18,0x21,
-0x08,0x00,0x25,0x5f,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xf5,0x00,0x00,0x00,0x00,
-0x08,0x00,0x25,0x5f,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x5f,0x24,0x04,0x08,0x44,
-0x02,0x40,0x20,0x21,0x0c,0x00,0x25,0x71,0x02,0x20,0x28,0x21,0x08,0x00,0x25,0x49,
-0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xe8,0x2c,0xc2,0x00,0x1f,0xaf,0xb0,0x00,0x10,
-0xaf,0xbf,0x00,0x14,0x00,0xc0,0x80,0x21,0x14,0x40,0x00,0x1d,0x30,0xa5,0x00,0xff,
-0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x18,0x28,0xa2,0x00,0x02,0x14,0x40,0x00,0x12,
-0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0e,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x07,
-0x24,0x04,0x08,0x4c,0x26,0x10,0xff,0xe2,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x14,
-0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x24,0x05,0xff,0xff,
-0x0c,0x00,0x13,0x5f,0x3c,0x06,0x0d,0xf8,0x08,0x00,0x25,0x82,0x26,0x10,0xff,0xe2,
-0x08,0x00,0x25,0x87,0x24,0x04,0x08,0x48,0x14,0xa0,0xff,0xf2,0x24,0x04,0x08,0x40,
-0x08,0x00,0x25,0x88,0x24,0x05,0xff,0xff,0x08,0x00,0x25,0x87,0x24,0x04,0x08,0x44,
-0x2c,0xc2,0x00,0x10,0x14,0x40,0xff,0xec,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x14,
-0x28,0xa2,0x00,0x02,0x14,0x40,0x00,0x0e,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0a,
-0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x03,0x24,0x04,0x08,0x4c,0x08,0x00,0x25,0x82,
-0x26,0x10,0xff,0xf1,0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5f,0x3c,0x06,0x0d,0xb8,
-0x08,0x00,0x25,0x82,0x26,0x10,0xff,0xf1,0x08,0x00,0x25,0xa1,0x24,0x04,0x08,0x48,
-0x14,0xa0,0xff,0xf6,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0xa2,0x24,0x05,0xff,0xff,
-0x08,0x00,0x25,0xa1,0x24,0x04,0x08,0x44,0x27,0xbd,0xff,0xe8,0x30,0x84,0x00,0xff,
-0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x39,0xaf,0xbf,0x00,0x10,0x28,0x82,0x00,0x02,
-0x14,0x40,0x00,0x27,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x17,
-0x00,0xa0,0x30,0x21,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0x05,0x24,0x04,0x08,0x3c,
-0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
-0x0c,0x00,0x13,0x5f,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x3c,0x3c,0x05,0x80,0x00,
-0x0c,0x00,0x13,0x5f,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x3c,0x3c,0x05,0x80,0x00,
-0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01,0x24,0x04,0x08,0xac,0x0c,0x00,0x13,0x41,
-0x24,0x05,0x0f,0xff,0x08,0x00,0x25,0xbc,0x00,0x00,0x00,0x00,0x24,0x04,0x08,0x34,
-0x0c,0x00,0x13,0x5f,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x34,0x3c,0x05,0x80,0x00,
-0x0c,0x00,0x13,0x5f,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x34,0x3c,0x05,0x80,0x00,
-0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01,0x08,0x00,0x25,0xcb,0x24,0x04,0x08,0xa8,
-0x14,0x80,0xff,0xdf,0x00,0xa0,0x30,0x21,0x24,0x04,0x08,0x24,0x0c,0x00,0x13,0x5f,
-0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x24,0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5f,
-0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x24,0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5f,
-0x24,0x06,0x00,0x01,0x08,0x00,0x25,0xcb,0x24,0x04,0x08,0xa0,0x00,0xa0,0x30,0x21,
-0x24,0x04,0x08,0x2c,0x0c,0x00,0x13,0x5f,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x2c,
-0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5f,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x2c,
-0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01,0x08,0x00,0x25,0xcb,
-0x24,0x04,0x08,0xa4,0x3c,0x05,0x00,0x14,0x3c,0x02,0xb0,0x05,0x34,0x42,0x04,0x20,
-0x3c,0x06,0xc0,0x00,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0x34,0xa5,0x17,0x09,
-0xac,0x45,0x00,0x00,0x34,0xc6,0x05,0x07,0x34,0x63,0x04,0x24,0x34,0x84,0x02,0x28,
-0x3c,0x07,0xb0,0x05,0x24,0x02,0x00,0x20,0xac,0x66,0x00,0x00,0x34,0xe7,0x04,0x50,
-0xa0,0x82,0x00,0x00,0x90,0xe2,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x03,
-0x10,0x40,0xff,0xfc,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x93,0x85,0x81,0xf1,0x24,0x02,0x00,0x01,0x14,0xa2,0x00,0x53,0x00,0x80,0x40,0x21,
-0x8c,0x89,0x00,0x04,0x3c,0x02,0xb0,0x01,0x01,0x22,0x30,0x21,0x8c,0xc3,0x00,0x04,
-0x3c,0x02,0x01,0x00,0x00,0x62,0x10,0x24,0x10,0x40,0x00,0x4b,0x30,0x62,0x00,0x08,
-0x10,0x45,0x00,0x59,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38,0x24,0x03,0x00,0xb4,
-0x30,0x44,0x00,0xff,0x10,0x83,0x00,0x61,0x24,0x02,0x00,0xc4,0x10,0x82,0x00,0x54,
-0x24,0x02,0x00,0x94,0x10,0x82,0x00,0x45,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38,
-0x00,0x00,0x00,0x00,0x30,0x47,0xff,0xff,0x30,0xe3,0x40,0xff,0x24,0x02,0x40,0x88,
-0x14,0x62,0x00,0x39,0x30,0xe3,0x03,0x00,0x24,0x02,0x03,0x00,0x10,0x62,0x00,0x38,
-0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x56,0x00,0x00,0x00,0x00,0x30,0x47,0xff,0xff,
-0x30,0xe2,0x00,0x80,0x14,0x40,0x00,0x30,0x3c,0x02,0xb0,0x01,0x01,0x22,0x30,0x21,
-0x94,0xc3,0x00,0x60,0x24,0x02,0x00,0x08,0x14,0x43,0x00,0x3b,0x00,0x00,0x00,0x00,
-0x90,0xc2,0x00,0x62,0x24,0x03,0x00,0x04,0x00,0x02,0x39,0x02,0x10,0xe3,0x00,0x15,
-0x24,0x02,0x00,0x06,0x14,0xe2,0x00,0x34,0x00,0x00,0x00,0x00,0x8d,0x05,0x01,0xac,
-0x94,0xc4,0x00,0x66,0x27,0x82,0x89,0x68,0x00,0x05,0x28,0x80,0x30,0x87,0xff,0xff,
-0x00,0xa2,0x28,0x21,0x00,0x07,0x1a,0x00,0x8c,0xa4,0x00,0x00,0x00,0x07,0x12,0x02,
-0x00,0x43,0x10,0x25,0x24,0x42,0x00,0x5e,0x24,0x03,0xc0,0x00,0x30,0x47,0xff,0xff,
-0x00,0x83,0x20,0x24,0x00,0x87,0x20,0x25,0xac,0xa4,0x00,0x00,0x08,0x00,0x26,0x76,
-0xad,0x07,0x00,0x10,0x8d,0x05,0x01,0xac,0x94,0xc4,0x00,0x64,0x27,0x82,0x89,0x68,
-0x00,0x05,0x28,0x80,0x30,0x87,0xff,0xff,0x00,0xa2,0x28,0x21,0x00,0x07,0x1a,0x00,
-0x8c,0xa4,0x00,0x00,0x00,0x07,0x12,0x02,0x00,0x43,0x10,0x25,0x24,0x42,0x00,0x36,
-0x3c,0x03,0xff,0xff,0x30,0x47,0xff,0xff,0x00,0x83,0x20,0x24,0x00,0x87,0x20,0x25,
-0xac,0xa4,0x00,0x00,0xad,0x07,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x94,0xc2,0x00,0x50,0x08,0x00,0x26,0x34,0x30,0x47,0xff,0xff,0x8d,0x04,0x01,0xac,
-0x27,0x83,0x89,0x68,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,
-0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x2e,0xac,0x82,0x00,0x00,
-0x24,0x03,0x00,0x2e,0xad,0x03,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x8d,0x04,0x01,0xac,0x27,0x83,0x89,0x68,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,
-0x8c,0x82,0x00,0x00,0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x0e,
-0x24,0x03,0x00,0x0e,0x08,0x00,0x26,0x75,0xac,0x82,0x00,0x00,0x8d,0x04,0x01,0xac,
-0x27,0x83,0x89,0x68,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,
-0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x14,0x24,0x03,0x00,0x14,
-0x08,0x00,0x26,0x75,0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x30,0xc6,0x00,0xff,0x00,0x06,0x48,0x40,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x8b,0xbc,0x30,0x27,0x83,0xbc,0x36,0x00,0x4b,0x40,0x21,0x00,0x43,0x10,0x21,
-0x94,0x47,0x00,0x00,0x30,0xa2,0x3f,0xff,0x10,0xe2,0x00,0x29,0x30,0x8a,0xff,0xff,
-0x95,0x02,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x02,0x11,0x82,0x30,0x42,0x00,0x01,
-0x10,0x43,0x00,0x18,0x00,0x00,0x00,0x00,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x4b,0x30,0x21,0x94,0xc4,0x00,0x02,0x27,0x83,0xbc,0x36,0x27,0x85,0xbc,0x34,
-0x00,0x45,0x28,0x21,0x30,0x84,0xff,0xdf,0x00,0x43,0x10,0x21,0xa4,0xc4,0x00,0x02,
-0xa4,0x40,0x00,0x00,0xa4,0xa0,0x00,0x00,0x94,0xc3,0x00,0x02,0x3c,0x04,0xb0,0x01,
-0x01,0x44,0x20,0x21,0x30,0x63,0xff,0xbf,0xa4,0xc3,0x00,0x02,0xa0,0xc0,0x00,0x00,
-0x8c,0x82,0x00,0x04,0x24,0x03,0xf0,0xff,0x00,0x43,0x10,0x24,0x03,0xe0,0x00,0x08,
-0xac,0x82,0x00,0x04,0x24,0x02,0xc0,0x00,0x91,0x04,0x00,0x01,0x00,0xa2,0x10,0x24,
-0x00,0x47,0x28,0x25,0x3c,0x03,0xb0,0x01,0x24,0x02,0x00,0x02,0x14,0x82,0xff,0xe2,
-0x01,0x43,0x18,0x21,0xac,0x65,0x00,0x00,0x08,0x00,0x26,0xa3,0x01,0x26,0x10,0x21,
-0x08,0x00,0x26,0xa3,0x01,0x26,0x10,0x21,0x93,0x83,0x81,0xf1,0x24,0x02,0x00,0x01,
-0x14,0x62,0x00,0x0d,0x3c,0x02,0xb0,0x01,0x8c,0x84,0x00,0x04,0x3c,0x06,0xb0,0x09,
-0x00,0x82,0x20,0x21,0x8c,0x85,0x00,0x08,0x8c,0x83,0x00,0x04,0x3c,0x02,0x01,0x00,
-0x34,0xc6,0x01,0x00,0x00,0x62,0x18,0x24,0x14,0x60,0x00,0x05,0x30,0xa5,0x20,0x00,
-0x24,0x02,0x00,0x06,0xa0,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x3c,0x03,0xb0,0x09,0x10,0xa0,0xff,0xfc,0x34,0x63,0x01,0x00,0x24,0x02,0x00,0x0e,
-0x08,0x00,0x26,0xd6,0xa0,0x62,0x00,0x00,0x3c,0x02,0xb0,0x01,0x30,0xa5,0xff,0xff,
-0x00,0xa2,0x28,0x21,0x8c,0xa3,0x00,0x00,0x3c,0x02,0x10,0x00,0x00,0x80,0x30,0x21,
-0x00,0x62,0x18,0x24,0x8c,0xa2,0x00,0x04,0x10,0x60,0x00,0x04,0x00,0x00,0x00,0x00,
-0x30,0x42,0x80,0x00,0x10,0x40,0x00,0x13,0x00,0x00,0x00,0x00,0x8c,0xc2,0x01,0xa8,
-0x00,0x00,0x00,0x00,0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,
-0x00,0x83,0x10,0x0a,0x93,0x83,0x81,0xf0,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,
-0x00,0x82,0x20,0x23,0x24,0x63,0xff,0xff,0xac,0xc4,0x01,0xa8,0xa3,0x83,0x81,0xf0,
-0x8c,0xc4,0x01,0xac,0x8c,0xc2,0x01,0xa8,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x26,
-0x00,0x02,0x10,0x2b,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x34,0x63,0x00,0x73,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,
-0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0xa3,0x80,0x81,0xf1,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0xa3,0x82,0x81,0xf1,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x3c,0x05,0xb0,0x01,0x00,0x80,0x50,0x21,
-0x00,0x45,0x10,0x21,0x8c,0x43,0x00,0x04,0x24,0x02,0x00,0x05,0x00,0x03,0x1a,0x02,
-0x30,0x69,0x00,0x0f,0x11,0x22,0x00,0x0b,0x24,0x02,0x00,0x07,0x11,0x22,0x00,0x09,
-0x24,0x02,0x00,0x0a,0x11,0x22,0x00,0x07,0x24,0x02,0x00,0x0b,0x11,0x22,0x00,0x05,
-0x24,0x02,0x00,0x01,0x93,0x83,0x81,0xf0,0x3c,0x04,0xb0,0x06,0x10,0x62,0x00,0x03,
-0x34,0x84,0x80,0x18,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x02,0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00,
-0x8d,0x43,0x01,0xa8,0x27,0x82,0x89,0x68,0x00,0x03,0x18,0x80,0x00,0x6a,0x20,0x21,
-0x8c,0x87,0x00,0xa8,0x00,0x62,0x18,0x21,0x8c,0x68,0x00,0x00,0x00,0xe5,0x28,0x21,
-0x8c,0xa9,0x00,0x00,0x3c,0x02,0xff,0xff,0x27,0x83,0x8a,0x68,0x01,0x22,0x10,0x24,
-0x00,0x48,0x10,0x25,0xac,0xa2,0x00,0x00,0x8d,0x44,0x01,0xa8,0x00,0x07,0x30,0xc2,
-0x3c,0x02,0x00,0x80,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x00,0x06,0x32,0x00,
-0x8c,0xa9,0x00,0x04,0x00,0xc2,0x30,0x25,0x8c,0x82,0x00,0x00,0x3c,0x03,0x80,0x00,
-0x01,0x22,0x10,0x25,0x00,0x43,0x10,0x25,0xac,0xa2,0x00,0x04,0xaf,0x87,0xbc,0x20,
-0x8c,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x82,0xbc,0x28,0x8c,0xa3,0x00,0x04,
-0x3c,0x01,0xb0,0x07,0xac,0x26,0x80,0x18,0x8d,0x42,0x01,0xa8,0xaf,0x83,0xbc,0x24,
-0x93,0x85,0x81,0xf0,0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,
-0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0xa5,0xff,0xff,
-0x00,0x82,0x20,0x23,0xad,0x44,0x01,0xa8,0xa3,0x85,0x81,0xf0,0x08,0x00,0x27,0x21,
-0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0xa5,0x00,0x20,
-0x24,0x42,0x9d,0x64,0xac,0xa2,0x00,0x00,0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x20,
-0xac,0x82,0x00,0x64,0x3c,0x02,0x80,0x01,0xac,0x83,0x00,0x60,0xac,0x80,0x00,0x00,
-0xac,0x80,0x00,0x04,0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x4c,0xac,0x80,0x00,0x50,
-0xac,0x80,0x00,0x54,0xac,0x80,0x00,0x0c,0xac,0x80,0x00,0x58,0xa0,0x80,0x00,0x5c,
-0x24,0x42,0x9e,0x28,0x24,0x83,0x00,0x68,0x24,0x05,0x00,0x0f,0x24,0xa5,0xff,0xff,
-0xac,0x62,0x00,0x00,0x04,0xa1,0xff,0xfd,0x24,0x63,0x00,0x04,0x3c,0x02,0x80,0x01,
-0x24,0x42,0x9f,0x10,0xac,0x82,0x00,0x78,0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01,
-0x24,0x63,0xa0,0x9c,0x24,0x42,0xa0,0x08,0xac,0x83,0x00,0x88,0xac,0x82,0x00,0x98,
-0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01,0x24,0x63,0xa1,0x44,0x24,0x42,0xa2,0x5c,
-0xac,0x83,0x00,0xa0,0xac,0x82,0x00,0xa4,0xa0,0x80,0x01,0xba,0xac,0x80,0x01,0xa8,
-0xac,0x80,0x01,0xac,0xac,0x80,0x01,0xb0,0xac,0x80,0x01,0xb4,0xa0,0x80,0x01,0xb8,
-0x03,0xe0,0x00,0x08,0xa0,0x80,0x01,0xb9,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,
-0x34,0x63,0x00,0x20,0x24,0x42,0x9e,0x28,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0x9e,0x40,
-0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x11,
-0x00,0x80,0x28,0x21,0x8c,0x82,0x00,0x14,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0d,
-0x00,0x00,0x00,0x00,0x8c,0x84,0x00,0x10,0x8c,0xa3,0x00,0x14,0x8c,0xa2,0x00,0x04,
-0x00,0x83,0x20,0x21,0x00,0x44,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b,
-0x00,0x02,0x12,0x02,0x00,0x43,0x10,0x21,0x00,0x02,0x12,0x00,0x30,0x42,0x3f,0xff,
-0xac,0xa2,0x00,0x04,0xac,0xa0,0x00,0x00,0xac,0xa0,0x00,0x4c,0xac,0xa0,0x00,0x50,
-0xac,0xa0,0x00,0x54,0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x0c,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,0x24,0x42,0x9e,0xbc,0xac,0x62,0x00,0x00,
-0x8c,0x86,0x00,0x04,0x3c,0x02,0xb0,0x01,0x24,0x03,0x00,0x01,0x00,0xc2,0x10,0x21,
-0x8c,0x45,0x00,0x00,0xac,0x83,0x00,0x4c,0x00,0x05,0x14,0x02,0x30,0xa3,0x3f,0xff,
-0x30,0x42,0x00,0xff,0xac,0x83,0x00,0x10,0xac,0x82,0x00,0x14,0x8c,0x83,0x00,0x14,
-0xac,0x85,0x00,0x40,0x00,0xc3,0x30,0x21,0x03,0xe0,0x00,0x08,0xac,0x86,0x00,0x08,
-0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,
-0x24,0x63,0x9f,0x10,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,
-0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x00,0x80,0x80,0x21,
-0xae,0x00,0x00,0x00,0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,
-0xae,0x00,0x00,0x0c,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x0c,0x00,0x27,0xaf,0x00,0x00,0x00,0x00,0x08,0x00,0x27,0xd1,
-0xae,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,
-0x34,0x42,0x00,0x20,0x24,0x63,0x9f,0x74,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,
-0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x16,
-0x00,0x80,0x80,0x21,0x8e,0x03,0x00,0x08,0x3c,0x02,0xb0,0x01,0x8e,0x04,0x00,0x44,
-0x00,0x62,0x18,0x21,0x90,0x65,0x00,0x00,0x24,0x02,0x00,0x01,0xae,0x02,0x00,0x50,
-0x30,0xa3,0x00,0xff,0x00,0x03,0x10,0x82,0x00,0x04,0x23,0x02,0x30,0x84,0x00,0x0f,
-0x30,0x42,0x00,0x03,0x00,0x03,0x19,0x02,0xae,0x04,0x00,0x34,0xae,0x02,0x00,0x2c,
-0xae,0x03,0x00,0x30,0xa2,0x05,0x00,0x48,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x27,0xaf,0x00,0x00,0x00,0x00,
-0x08,0x00,0x27,0xe9,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,
-0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa0,0x08,0xaf,0xb0,0x00,0x10,
-0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x16,0x00,0x80,0x80,0x21,0x92,0x03,0x00,0x44,0x8e,0x02,0x00,0x40,
-0x83,0x85,0x8b,0xd4,0x92,0x04,0x00,0x41,0x30,0x63,0x00,0x01,0x00,0x02,0x16,0x02,
-0xae,0x04,0x00,0x14,0x00,0x00,0x30,0x21,0xae,0x02,0x00,0x18,0x10,0xa0,0x00,0x04,
-0xae,0x03,0x00,0x3c,0x10,0x60,0x00,0x03,0x24,0x02,0x00,0x01,0x24,0x06,0x00,0x01,
-0x24,0x02,0x00,0x01,0xa3,0x86,0x8b,0xd4,0x8f,0xbf,0x00,0x14,0xae,0x02,0x00,0x54,
-0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x27,0xdd,
-0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x0e,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa0,0x9c,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x1b,0x00,0x80,0x80,0x21,0x3c,0x02,0xb0,0x03,
-0x8c,0x42,0x00,0x00,0x92,0x04,0x00,0x44,0x8e,0x03,0x00,0x40,0x83,0x86,0x8b,0xd4,
-0x92,0x05,0x00,0x41,0x30,0x42,0x08,0x00,0x30,0x84,0x00,0x01,0x00,0x02,0x12,0xc2,
-0x00,0x03,0x1e,0x02,0x00,0x82,0x20,0x25,0xae,0x05,0x00,0x14,0x00,0x00,0x38,0x21,
-0xae,0x03,0x00,0x18,0x10,0xc0,0x00,0x04,0xae,0x04,0x00,0x3c,0x10,0x80,0x00,0x03,
-0x24,0x02,0x00,0x01,0x24,0x07,0x00,0x01,0x24,0x02,0x00,0x01,0xa3,0x87,0x8b,0xd4,
-0x8f,0xbf,0x00,0x14,0xae,0x02,0x00,0x54,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x0c,0x00,0x27,0xdd,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x33,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,
-0x34,0x42,0x00,0x20,0x24,0x63,0xa1,0x44,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,
-0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x37,
-0x00,0x80,0x80,0x21,0x8e,0x04,0x00,0x04,0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00,
-0x3c,0x05,0xb0,0x01,0x34,0x42,0x00,0x10,0x00,0x85,0x20,0x21,0x00,0x62,0x18,0x25,
-0xac,0x83,0x00,0x04,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x02,0x00,0x20,0x21,
-0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x00,0x00,0x03,0x18,0x80,0x27,0x82,0x89,0x68,
-0x00,0x62,0x18,0x21,0xac,0x66,0x00,0x00,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,
-0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x04,0x00,0x03,0x18,0x80,0x27,0x82,0x8a,0x68,
-0x00,0x62,0x18,0x21,0x0c,0x00,0x26,0x10,0xac,0x66,0x00,0x00,0x8e,0x03,0x01,0xac,
-0x8e,0x07,0x00,0x04,0x3c,0x06,0xb0,0x03,0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00,
-0x24,0x62,0x00,0x40,0x00,0xa4,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,
-0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x23,0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac,
-0xac,0x67,0x00,0xa8,0x34,0xc6,0x00,0x30,0x8c,0xc3,0x00,0x00,0x93,0x82,0x81,0xf0,
-0x02,0x00,0x20,0x21,0x24,0x63,0x00,0x01,0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00,
-0xa3,0x82,0x81,0xf0,0x0c,0x00,0x27,0x90,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,
-0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0x27,
-0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x5d,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa2,0x5c,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x54,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x37,0x00,0x80,0x80,0x21,0x8e,0x04,0x00,0x04,
-0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x01,0x34,0x42,0x00,0x10,
-0x00,0x85,0x20,0x21,0x00,0x62,0x18,0x25,0xac,0x83,0x00,0x04,0x8e,0x02,0x00,0x04,
-0x8e,0x03,0x01,0xac,0x02,0x00,0x20,0x21,0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x00,
-0x00,0x03,0x18,0x80,0x27,0x82,0x89,0x68,0x00,0x62,0x18,0x21,0xac,0x66,0x00,0x00,
-0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x04,
-0x00,0x03,0x18,0x80,0x27,0x82,0x8a,0x68,0x00,0x62,0x18,0x21,0x0c,0x00,0x26,0x10,
-0xac,0x66,0x00,0x00,0x8e,0x03,0x01,0xac,0x8e,0x07,0x00,0x04,0x3c,0x06,0xb0,0x03,
-0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0x62,0x00,0x40,0x00,0xa4,0x10,0x0a,
-0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x23,
-0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac,0xac,0x67,0x00,0xa8,0x34,0xc6,0x00,0x30,
-0x8c,0xc3,0x00,0x00,0x93,0x82,0x81,0xf0,0x02,0x00,0x20,0x21,0x24,0x63,0x00,0x01,
-0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00,0xa3,0x82,0x81,0xf0,0x0c,0x00,0x27,0x90,
-0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0x27,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0xa3,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,
-0x24,0x63,0xa3,0x74,0x27,0xbd,0xff,0xe0,0xac,0x43,0x00,0x00,0x3c,0x02,0x80,0x01,
-0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c,
-0x00,0x80,0x80,0x21,0x24,0x52,0x9e,0x28,0x00,0x00,0x88,0x21,0x3c,0x03,0xb0,0x09,
-0x34,0x63,0x00,0x06,0x8e,0x06,0x00,0x04,0x90,0x62,0x00,0x00,0x00,0x06,0x22,0x02,
-0x00,0x44,0x10,0x23,0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x7f,
-0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0x84,0xff,0xff,
-0x10,0x44,0x00,0x68,0x00,0x00,0x28,0x21,0x3c,0x02,0xb0,0x01,0x00,0xc2,0x10,0x21,
-0x8c,0x44,0x00,0x04,0x3c,0x03,0x7c,0x00,0x34,0x63,0x00,0xf0,0x00,0x83,0x18,0x24,
-0xae,0x04,0x00,0x44,0x8c,0x44,0x00,0x00,0x10,0x60,0x00,0x69,0x00,0x00,0x38,0x21,
-0x3c,0x09,0xb0,0x03,0x3c,0x06,0x7c,0x00,0x35,0x29,0x00,0x99,0x3c,0x0a,0xb0,0x01,
-0x24,0x08,0x00,0x40,0x34,0xc6,0x00,0xf0,0x3c,0x0b,0xff,0xff,0x3c,0x0c,0x28,0x38,
-0x16,0x20,0x00,0x06,0x24,0xa5,0x00,0x01,0x93,0x82,0x81,0xf6,0x24,0x11,0x00,0x01,
-0x24,0x42,0x00,0x01,0xa1,0x22,0x00,0x00,0xa3,0x82,0x81,0xf6,0x8e,0x02,0x00,0x04,
-0x24,0x07,0x00,0x01,0x24,0x42,0x01,0x00,0x30,0x42,0x3f,0xff,0xae,0x02,0x00,0x04,
-0x00,0x4a,0x10,0x21,0x8c,0x43,0x00,0x04,0x00,0x00,0x00,0x00,0xae,0x03,0x00,0x44,
-0x8c,0x44,0x00,0x00,0x10,0xa8,0x00,0x2d,0x00,0x66,0x18,0x24,0x14,0x60,0xff,0xec,
-0x00,0x8b,0x10,0x24,0x14,0x4c,0xff,0xea,0x24,0x02,0x00,0x01,0x10,0xe2,0x00,0x2f,
-0x3c,0x03,0xb0,0x09,0x8e,0x02,0x00,0x44,0x8e,0x04,0x00,0x60,0x00,0x02,0x1e,0x42,
-0x00,0x02,0x12,0x02,0x30,0x42,0x00,0x0f,0x30,0x63,0x00,0x01,0xae,0x02,0x00,0x00,
-0x10,0x44,0x00,0x1a,0xae,0x03,0x00,0x58,0x8e,0x02,0x00,0x64,0x8e,0x04,0x00,0x58,
-0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x05,0x00,0x00,0x00,0x00,0xae,0x00,0x00,0x4c,
-0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,0xae,0x00,0x00,0x0c,0x8e,0x03,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x80,0x00,0x50,0x10,0x21,0x8c,0x42,0x00,0x68,
-0x00,0x00,0x00,0x00,0x10,0x52,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x40,0xf8,0x09,
-0x02,0x00,0x20,0x21,0x8e,0x04,0x00,0x58,0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
-0xae,0x03,0x00,0x60,0x08,0x00,0x28,0xeb,0xae,0x04,0x00,0x64,0x8e,0x02,0x00,0x64,
-0x00,0x00,0x00,0x00,0x14,0x62,0xff,0xe5,0x00,0x00,0x00,0x00,0x7a,0x02,0x0d,0x7c,
-0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x00,0x43,0x10,0x26,
-0x00,0x02,0x10,0x2b,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x34,0x63,0x00,0x06,
-0x8e,0x04,0x00,0x04,0x90,0x62,0x00,0x00,0x00,0x04,0x22,0x02,0x00,0x44,0x10,0x23,
-0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x7f,0x00,0x83,0x10,0x0a,
-0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0x14,0x87,0xff,0xc5,
-0x00,0x00,0x00,0x00,0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x03,
-0x14,0x40,0x00,0x05,0x24,0x02,0x00,0x0d,0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x01,
-0x08,0x00,0x29,0x4b,0xa2,0x02,0x00,0x5c,0x08,0x00,0x29,0x4b,0xa2,0x00,0x00,0x5c,
-0x3c,0x02,0xff,0xff,0x00,0x82,0x10,0x24,0x3c,0x03,0x28,0x38,0x14,0x43,0xff,0x94,
-0x24,0x02,0x00,0x01,0x08,0x00,0x29,0x23,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0xa5,0xcc,0xac,0x43,0x00,0x00,
-0x8c,0x83,0x01,0xa8,0x8c,0x82,0x01,0xac,0x00,0x80,0x40,0x21,0x10,0x62,0x00,0x20,
-0x00,0x00,0x20,0x21,0x93,0x82,0x81,0xf1,0x00,0x03,0x28,0x80,0x3c,0x07,0xb0,0x06,
-0x00,0xa8,0x18,0x21,0x24,0x04,0x00,0x01,0x8c,0x66,0x00,0xa8,0x10,0x44,0x00,0x1c,
-0x34,0xe7,0x80,0x18,0x3c,0x05,0xb0,0x01,0xaf,0x86,0xbc,0x20,0x00,0xc5,0x28,0x21,
-0x8c,0xa3,0x00,0x00,0x00,0x06,0x20,0xc2,0x3c,0x02,0x00,0x80,0x00,0x04,0x22,0x00,
-0x00,0x82,0x20,0x25,0xaf,0x83,0xbc,0x28,0x8c,0xa2,0x00,0x04,0xac,0xe4,0x00,0x00,
-0x8d,0x03,0x01,0xa8,0xaf,0x82,0xbc,0x24,0x24,0x64,0x00,0x01,0x04,0x80,0x00,0x0a,
-0x00,0x80,0x10,0x21,0x00,0x02,0x11,0x83,0x8d,0x03,0x01,0xac,0x00,0x02,0x11,0x80,
-0x00,0x82,0x10,0x23,0x00,0x43,0x18,0x26,0xad,0x02,0x01,0xa8,0x00,0x03,0x20,0x2b,
-0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x08,0x00,0x29,0x95,0x24,0x62,0x00,0x40,
-0x27,0x82,0x89,0x68,0x00,0x06,0x20,0xc2,0x00,0x04,0x22,0x00,0x00,0xa2,0x48,0x21,
-0x3c,0x02,0x00,0x80,0x00,0x82,0x58,0x25,0x93,0x82,0x81,0xf0,0x3c,0x0a,0xb0,0x06,
-0x3c,0x03,0xb0,0x01,0x2c,0x42,0x00,0x02,0x00,0xc3,0x38,0x21,0x35,0x4a,0x80,0x18,
-0x14,0x40,0xff,0xef,0x00,0x00,0x20,0x21,0x8c,0xe5,0x00,0x00,0x8d,0x23,0x00,0x00,
-0x24,0x02,0xc0,0x00,0x00,0xa2,0x10,0x24,0x00,0x43,0x10,0x25,0xac,0xe2,0x00,0x00,
-0x8d,0x04,0x01,0xa8,0x27,0x83,0x8a,0x68,0x8c,0xe5,0x00,0x04,0x00,0x04,0x20,0x80,
-0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0x80,0x00,0x00,0xa2,0x10,0x25,
-0x00,0x43,0x10,0x25,0xac,0xe2,0x00,0x04,0xaf,0x86,0xbc,0x20,0x8c,0xe2,0x00,0x00,
-0x93,0x85,0x81,0xf0,0xaf,0x82,0xbc,0x28,0x8c,0xe3,0x00,0x04,0xad,0x4b,0x00,0x00,
-0x8d,0x02,0x01,0xa8,0xaf,0x83,0xbc,0x24,0x24,0xa5,0xff,0xff,0x24,0x44,0x00,0x01,
-0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,
-0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0xad,0x04,0x01,0xa8,0xa3,0x85,0x81,0xf0,
-0x79,0x02,0x0d,0x7c,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x26,0x08,0x00,0x29,0x9c,
-0x00,0x02,0x20,0x2b,0x3c,0x04,0xb0,0x03,0x3c,0x06,0xb0,0x07,0x3c,0x02,0x80,0x01,
-0x34,0xc6,0x00,0x18,0x34,0x84,0x00,0x20,0x24,0x42,0xa7,0x54,0x24,0x03,0xff,0x83,
-0xac,0x82,0x00,0x00,0xa0,0xc3,0x00,0x00,0x90,0xc4,0x00,0x00,0x27,0xbd,0xff,0xf8,
-0x3c,0x03,0xb0,0x07,0x24,0x02,0xff,0x82,0xa3,0xa4,0x00,0x00,0xa0,0x62,0x00,0x00,
-0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x08,0xa3,0xa4,0x00,0x01,
-0xa0,0x40,0x00,0x00,0x90,0x43,0x00,0x00,0x24,0x02,0x00,0x03,0x3c,0x05,0xb0,0x07,
-0xa3,0xa3,0x00,0x00,0xa0,0xc2,0x00,0x00,0x90,0xc4,0x00,0x00,0x34,0xa5,0x00,0x10,
-0x24,0x02,0x00,0x06,0x3c,0x03,0xb0,0x07,0xa3,0xa4,0x00,0x00,0x34,0x63,0x00,0x38,
-0xa0,0xa2,0x00,0x00,0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x20,
-0xa3,0xa4,0x00,0x00,0xa0,0xa0,0x00,0x00,0x90,0xa3,0x00,0x00,0xaf,0x82,0xbf,0x30,
-0xa3,0xa3,0x00,0x00,0xa0,0x40,0x00,0x00,0x90,0x43,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x08,};
-
-u8 Rtl8192PciEFwDataArray[DataArrayLengthPciE] = {
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x00,
-0x02,0xe9,0x01,0x74,0x02,0xab,0x01,0xc7,0x01,0x55,0x00,0xe4,0x00,0xab,0x00,0x72,
-0x00,0x55,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x02,0x76,0x01,0x3b,
-0x00,0xd2,0x00,0x9e,0x00,0x69,0x00,0x4f,0x00,0x46,0x00,0x3f,0x01,0x3b,0x00,0x9e,
-0x00,0x69,0x00,0x4f,0x00,0x35,0x00,0x27,0x00,0x23,0x00,0x20,0x01,0x2f,0x00,0x98,
-0x00,0x65,0x00,0x4c,0x00,0x33,0x00,0x26,0x00,0x22,0x00,0x1e,0x00,0x98,0x00,0x4c,
-0x00,0x33,0x00,0x26,0x00,0x19,0x00,0x13,0x00,0x11,0x00,0x0f,0x02,0x39,0x01,0x1c,
-0x00,0xbd,0x00,0x8e,0x00,0x5f,0x00,0x47,0x00,0x3f,0x00,0x39,0x01,0x1c,0x00,0x8e,
-0x00,0x5f,0x00,0x47,0x00,0x2f,0x00,0x23,0x00,0x20,0x00,0x1c,0x01,0x11,0x00,0x89,
-0x00,0x5b,0x00,0x44,0x00,0x2e,0x00,0x22,0x00,0x1e,0x00,0x1b,0x00,0x89,0x00,0x44,
-0x00,0x2e,0x00,0x22,0x00,0x17,0x00,0x11,0x00,0x0f,0x00,0x0e,0x02,0xab,0x02,0xab,
-0x02,0x66,0x02,0x66,0x07,0x06,0x06,0x06,0x05,0x06,0x07,0x08,0x04,0x06,0x07,0x08,
-0x09,0x0a,0x0b,0x0b,0x49,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x4c,
-0x42,0x4d,0x4f,0x44,0x00,0x00,0x00,0x00,0x54,0x4c,0x42,0x4c,0x5f,0x64,0x61,0x74,
-0x61,0x00,0x54,0x4c,0x42,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x64,0x45,0x4c,
-0x5f,0x64,0x61,0x74,0x61,0x00,0x41,0x64,0x45,0x53,0x00,0x00,0x00,0x00,0x00,0x00,
-0x45,0x78,0x63,0x43,0x6f,0x64,0x65,0x36,0x00,0x00,0x45,0x78,0x63,0x43,0x6f,0x64,
-0x65,0x37,0x00,0x00,0x53,0x79,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x70,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x49,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x43,0x70,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0x76,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x0b,0x63,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x2c,
-0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x60,
-0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xc0,0x00,0x00,0x01,0x20,0x00,0x00,0x01,0x80,
-0x00,0x00,0x01,0xb0,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x9c,
-0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0x38,0x00,0x00,0x01,0xa0,0x00,0x00,0x01,0xd4,
-0x00,0x00,0x02,0x08,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0x38,
-0x00,0x00,0x01,0xa0,0x00,0x00,0x02,0x6f,0x00,0x00,0x03,0x40,0x00,0x00,0x03,0xa8,
-0x00,0x00,0x04,0x10,0x01,0x01,0x01,0x02,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,
-0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x07,0x6c,0x80,0x00,0x07,0x80,
-0x80,0x00,0x07,0x80,0x80,0x00,0x07,0x70,0x80,0x00,0x07,0x70,0x80,0x00,0x07,0x94,
-0x80,0x00,0x56,0xb0,0x80,0x00,0x57,0x08,0x80,0x00,0x57,0x30,0x80,0x00,0x58,0x28,
-0x80,0x00,0x58,0xe0,0x80,0x00,0x59,0x88,0x80,0x00,0x59,0xfc,0x80,0x00,0x5b,0x08,
-0x80,0x00,0x5b,0x40,0x80,0x00,0x5b,0x54,0x80,0x00,0x5b,0x68,0x80,0x00,0x5c,0x50,
-0x80,0x00,0x5c,0x90,0x80,0x00,0x5d,0x44,0x80,0x00,0x5d,0x6c,0x80,0x00,0x56,0x70,
-0x80,0x00,0x5d,0xbc,0x80,0x00,0x64,0x48,0x80,0x00,0x64,0xc0,0x80,0x00,0x64,0xcc,
-0x80,0x00,0x64,0xd8,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,
-0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,
-0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,
-0x80,0x00,0x64,0x60,0x80,0x00,0x64,0xe4,0x80,0x00,0x64,0xf0,0x80,0x00,0x64,0xfc,
-0x80,0x00,0x87,0xa4,0x80,0x00,0x87,0xa4,0x80,0x00,0x87,0xa4,0x80,0x00,0x87,0xd8,
-0x80,0x00,0x88,0x18,0x80,0x00,0x88,0x50,0x80,0x00,0x88,0x80,0x80,0x00,0x88,0xb0,
-0x80,0x00,0x88,0xc4,0x80,0x00,0x89,0x2c,0x80,0x00,0x89,0x40,0x80,0x00,0x89,0x7c,
-0x80,0x00,0x89,0x84,0x80,0x00,0x89,0xc0,0x80,0x00,0x89,0xd4,0x80,0x00,0x89,0xdc,
-0x80,0x00,0x89,0xe4,0x80,0x00,0x89,0xe4,0x80,0x00,0x89,0xe4,0x80,0x00,0x89,0xe4,
-0x80,0x00,0x8a,0x14,0x80,0x00,0x8a,0x28,0x80,0x00,0x8a,0x3c,0x80,0x00,0x86,0xe8,
-0x80,0x00,0x8d,0x68,0x80,0x00,0x8d,0x68,0x80,0x00,0x8d,0x68,0x80,0x00,0x8d,0x9c,
-0x80,0x00,0x8d,0xdc,0x80,0x00,0x8e,0x14,0x80,0x00,0x8e,0x44,0x80,0x00,0x8e,0x74,
-0x80,0x00,0x8e,0x88,0x80,0x00,0x8e,0xf0,0x80,0x00,0x8f,0x04,0x80,0x00,0x8f,0x40,
-0x80,0x00,0x8f,0x48,0x80,0x00,0x8f,0x84,0x80,0x00,0x8f,0x98,0x80,0x00,0x8f,0xa0,
-0x80,0x00,0x8f,0xa8,0x80,0x00,0x8f,0xa8,0x80,0x00,0x8f,0xa8,0x80,0x00,0x8f,0xa8,
-0x80,0x00,0x8f,0xd8,0x80,0x00,0x8f,0xec,0x80,0x00,0x90,0x00,0x80,0x00,0x8b,0x88,
-};
-
u32 Rtl8192PciEPHY_REGArray[PHY_REGArrayLengthPciE] = {0x0,};
u32 Rtl8192PciEPHY_REG_1T2RArray[PHY_REG_1T2RArrayLengthPciE] = {
default:
bResult = false;
- RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state"
+ RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknown state"
" to set: 0x%X!!!\n", eRFPowerState);
break;
}
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->ethtool_ops = &rtl819x_ethtool_ops;
dev->type = ARPHRD_ETHER;
RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n",
__func__);
priv->bdisable_nic = false;
- return RT_STATUS_FAILURE;
+ return false;
}
RT_TRACE(COMP_PS, "===========>%s()\n", __func__);
RT_TRACE(COMP_ERR, "ERR!!! %s(): initialization is failed!\n",
__func__);
priv->bdisable_nic = false;
- return -1;
+ return false;
}
RT_TRACE(COMP_INIT, "start adapter finished\n");
RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
struct rt_firmware *pFirmware;
enum rtl819x_loopback LoopbackMode;
- enum firmware_source firmware_source;
struct timer_list watch_dog_timer;
struct timer_list fsync_timer;
#include <linux/string.h>
#include "rtl_core.h"
+#include "rtl_wx.h"
#define RATE_COUNT 12
static u32 rtl8192_rates[] = {
};
/*
- * the following rule need to be follwing,
+ * the following rule need to be following,
* Odd : get (world access),
* even : set (root access)
* */
return wstats;
}
-struct iw_handler_def r8192_wx_handlers_def = {
+const struct iw_handler_def r8192_wx_handlers_def = {
.standard = r8192_wx_handlers,
.num_standard = ARRAY_SIZE(r8192_wx_handlers),
.private = r8192_private_handler,
struct iw_handler_def;
struct iw_statistics;
-extern struct iw_handler_def r8192_wx_handlers_def;
-struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
+extern const struct iw_handler_def r8192_wx_handlers_def;
u16 rtl8192_11n_user_show_rates(struct net_device *dev);
#endif
BAReq->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT);
tag = (u8 *)skb_put(skb, 9);
- *tag ++= ACT_CAT_BA;
- *tag ++= type;
- *tag ++= pBA->DialogToken;
+ *tag++ = ACT_CAT_BA;
+ *tag++ = type;
+ *tag++ = pBA->DialogToken;
if (ACT_ADDBARSP == type) {
RT_TRACE(COMP_DBG, "====>to send ADDBARSP\n");
tag = (u8 *)skb_put(skb, 6);
- *tag ++= ACT_CAT_BA;
- *tag ++= ACT_DELBA;
+ *tag++ = ACT_CAT_BA;
+ *tag++ = ACT_DELBA;
tmp = DelbaParamSet.shortData;
memcpy(tag, (u8 *)&tmp, 2);
if (skb)
softmac_mgmt_xmit(skb, ieee);
else
- RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in func"
- "tion %s()\n", __func__);
+ RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function"
+ " %s()\n", __func__);
return ;
}
if (index > REORDER_WIN_SIZE) {
RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket():"
- " Rx Reorer struct buffer full!!\n");
+ " Rx Reorder struct buffer full!!\n");
spin_unlock_irqrestore(&(ieee->reorder_spinlock),
flags);
return;
if (index > REORDER_WIN_SIZE) {
RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket():"
- " Rx Reorer struct buffer full!!\n");
+ " Rx Reorder struct buffer full!!\n");
spin_unlock_irqrestore(&(ieee->reorder_spinlock),
flags);
return;
goto out; /* scan completed */
} while (!ieee->active_channel_map[ch]);
- /* this fuction can be called in two situations
+ /* this function can be called in two situations
* 1- We have switched to ad-hoc mode and we are
* performing a complete syncro scan before conclude
* there are no interesting cell and to create a
}
tmp = *act;
act ++;
- switch (tmp)
- {
- case ACT_CAT_BA:
- if (*act == ACT_ADDBAREQ)
+ switch (tmp) {
+ case ACT_CAT_BA:
+ if (*act == ACT_ADDBAREQ)
ieee80211_rx_ADDBAReq(ieee, skb);
- else if (*act == ACT_ADDBARSP)
+ else if (*act == ACT_ADDBARSP)
ieee80211_rx_ADDBARsp(ieee, skb);
- else if (*act == ACT_DELBA)
+ else if (*act == ACT_DELBA)
ieee80211_rx_DELBA(ieee, skb);
- break;
- default:
-// if (net_ratelimit())
-// IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp);
- break;
+ break;
+ default:
+ break;
}
return;
for(eRFPath = 0; eRFPath <RF90_PATH_MAX; eRFPath++)
{
if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
- continue;
+ continue;
switch (Bandwidth)
{
for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++)
{
if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
- continue;
+ continue;
pPhyReg = &priv->PHYRegDef[eRFPath];
if(priv->CustomerID == RT_CID_819x_Netcore)
TxAGC = 0x22;
else
- TxAGC += priv->CckPwEnl;
+ TxAGC += priv->CckPwEnl;
}
if(TxAGC > 0x24)
curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
- if((curTxOkCnt + curRxOkCnt) < 15000000) {
+ if ((curTxOkCnt + curRxOkCnt) < 15000000)
return;
- }
if(curTxOkCnt > 4*curRxOkCnt) {
if (priv->bCurrentRxAggrEnable) {
write_nic_byte(dev, UFWP, 1);
}
//Restore TX Power Tracking Index
- if(priv->btxpower_trackingInit && priv->btxpower_tracking){
+ if (priv->btxpower_trackingInit && priv->btxpower_tracking)
dm_txpower_reset_recovery(dev);
- }
//
//Restore BB Initial Gain
range->num_bitrates = RATE_COUNT;
- for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
+ for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
range->bitrate[i] = rtl8180_rates[i];
- }
range->min_frag = MIN_FRAG_THRESHOLD;
range->max_frag = MAX_FRAG_THRESHOLD;
* and Tx descriptor info
* */
rt_status = fw_download_code(dev,mapped_file,file_length);
- if (rst_opt == OPT_SYSTEM_RESET) {
+ if (rst_opt == OPT_SYSTEM_RESET)
release_firmware(fw_entry);
- }
- if (rt_status != TRUE) {
+ if (rt_status != TRUE)
goto download_firmware_fail;
- }
switch (init_step) {
case FW_INIT_STEP0_BOOT:
pdwArray = rtl819XMACPHY_Array;
}
for (i = 0; i < dwArrayLen; i = i+3) {
- if (pdwArray[i] == 0x318) {
+ if (pdwArray[i] == 0x318)
pdwArray[i+2] = 0x00000800;
- }
RT_TRACE(COMP_DBG,
"Rtl8190MACPHY_Array[0]=%x Rtl8190MACPHY_Array[1]=%x Rtl8190MACPHY_Array[2]=%x\n",
struct sta_info *psta;
struct sta_priv *pstapriv;
union recv_frame *prtnframe;
- u16 ether_type = 0;
+ u16 ether_type;
pstapriv = &adapter->stapriv;
ptr = get_recvframe_data(precv_frame);
psta = r8712_get_stainfo(pstapriv, psta_addr);
auth_alg = adapter->securitypriv.AuthAlgrthm;
if (auth_alg == 2) {
+ /* get ether_type */
+ ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE;
+ memcpy(ðer_type, ptr, 2);
+ ether_type = ntohs((unsigned short)ether_type);
+
if ((psta != NULL) && (psta->ieee8021x_blocked)) {
/* blocked
* only accept EAPOL frame */
- prtnframe = precv_frame;
- /*get ether_type */
- ptr = ptr + pfhdr->attrib.hdrlen +
- pfhdr->attrib.iv_len + LLC_HEADER_SIZE;
- memcpy(ðer_type, ptr, 2);
- ether_type = ntohs((unsigned short)ether_type);
if (ether_type == 0x888e)
prtnframe = precv_frame;
else {
will never be used as an AP, or the target system has limited memory,
"Y" should be selected.
-config 8723AU_P2P
- bool "Realtek RTL8723AU Peer-to-peer mode"
- default y
- ---help---
- This option enables peer-to-peer mode for the r8723au driver. Unless you
- know that peer-to-peer (P2P) mode will never be used, or the target system has
- limited memory, "Y" should be selected.
-
config 8723AU_BT_COEXIST
bool "Realtek RTL8723AU BlueTooth Coexistence"
default y
core/rtw_led.o \
core/rtw_mlme.o \
core/rtw_mlme_ext.o \
- core/rtw_p2p.o \
core/rtw_pwrctrl.o \
core/rtw_recv.o \
core/rtw_security.o \
#ifdef CONFIG_8723AU_AP_MODE
-extern unsigned char RTW_WPA_OUI23A[];
extern unsigned char WMM_OUI23A[];
extern unsigned char WPS_OUI23A[];
extern unsigned char P2P_OUI23A[];
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;
- u16 tim_bitmap_le;
+ __le16 tim_bitmap_le;
uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);
- p = rtw_get_ie23a(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);
+ p = rtw_get_ie23a(pie + _FIXED_IE_LENGTH_, WLAN_EID_TIM, &tim_ielen,
+ pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);
if (p != NULL && tim_ielen>0) {
tim_ielen += 2;
offset = _FIXED_IE_LENGTH_;
/* get ssid_ie len */
- p = rtw_get_ie23a(pie + _BEACON_IE_OFFSET_, _SSID_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(pie + _BEACON_IE_OFFSET_, WLAN_EID_SSID,
+ &tmp_len, (pnetwork_mlmeext->IELength -
+ _BEACON_IE_OFFSET_));
if (p != NULL)
offset += tmp_len+2;
/* get supported rates len */
- p = rtw_get_ie23a(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(pie + _BEACON_IE_OFFSET_, WLAN_EID_SUPP_RATES,
+ &tmp_len, (pnetwork_mlmeext->IELength -
+ _BEACON_IE_OFFSET_));
if (p != NULL)
offset += tmp_len+2;
memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
}
- *dst_ie++= _TIM_IE_;
+ *dst_ie++= WLAN_EID_TIM;
if ((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fc))
tim_ielen = 5;
/* to update bcn with tim_bitmap for this station */
pstapriv->tim_bitmap |= CHKBIT(psta->aid);
- update_beacon23a(padapter, _TIM_IE_, NULL, false);
+ update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
if (!pmlmeext->active_keep_alive_check)
continue;
unsigned int tx_ra_bitmap = 0;
struct ht_priv *psta_ht = NULL;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
+ struct wlan_bssid_ex *pcur_network = &pmlmepriv->cur_network.network;
if (psta)
psta_ht = &psta->htpriv;
tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value23a(psta->bssrateset[i]&0x7f);
}
/* n mode ra_bitmap */
- if (psta_ht->ht_option)
- {
- rtw23a_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+ if (psta_ht->ht_option) {
+ rf_type = rtl8723a_get_rf_type(padapter);
+
if (rf_type == RF_2T2R)
limit = 16;/* 2R */
else
int i, supportRateNum = 0;
unsigned int tx_ra_bitmap = 0;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
+ struct wlan_bssid_ex *pcur_network = &pmlmepriv->cur_network.network;
struct sta_info *psta = rtw_get_bcmc_stainfo23a(padapter);
if (psta)
psta->raid = raid;
psta->init_rate = init_rate;
- rtw_stassoc_hw_rpt23a(padapter, psta);
-
spin_lock_bh(&psta->lock);
psta->state = _FW_LINKED;
spin_unlock_bh(&psta->lock);
min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
-
- rtw_hal_set_hwreg23a(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
+ 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 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
static void start_bss_network(struct rtw_adapter *padapter, u8 *pbuf)
{
- u8 *p;
+ const u8 *p;
u8 val8, cur_channel, cur_bwmode, cur_ch_offset;
u16 bcn_interval;
u32 acparm;
- int ie_len;
struct registry_priv *pregpriv = &padapter->registrypriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct security_priv* psecuritypriv = &padapter->securitypriv;
- struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
+ 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 HT_info_element *pht_info = NULL;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif /* CONFIG_8723AU_P2P */
bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
cur_channel = pnetwork->Configuration.DSConfig;
Set_MSR23a(padapter, _HW_STATE_AP_);
/* Set BSSID REG */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID, pnetwork->MacAddress);
+ hw_var_set_bssid(padapter, pnetwork->MacAddress);
/* Set EDCA param reg */
acparm = 0x002F3217; /* VO */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
+ rtl8723a_set_ac_param_vo(padapter, acparm);
acparm = 0x005E4317; /* VI */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
+ rtl8723a_set_ac_param_vi(padapter, acparm);
acparm = 0x005ea42b;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
+ rtl8723a_set_ac_param_be(padapter, acparm);
acparm = 0x0000A444; /* BK */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
+ rtl8723a_set_ac_param_bk(padapter, acparm);
/* Set Security */
- val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
+ val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ?
+ 0xcc: 0xcf;
+ rtl8723a_set_sec_cfg(padapter, val8);
/* Beacon Control related register */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));
+ rtl8723a_set_beacon_interval(padapter, bcn_interval);
UpdateBrateTbl23a(padapter, pnetwork->SupportedRates);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BASIC_RATE, 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 */
- Switch_DM_Func23a(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
+ rtl8723a_odm_support_ability_set(padapter,
+ DYNAMIC_ALL_FUNC_ENABLE);
}
/* set channel, bwmode */
- p = rtw_get_ie23a((pnetwork->IEs + sizeof(struct ndis_802_11_fixed_ies)),
- _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength -
- sizeof(struct ndis_802_11_fixed_ies)));
- if (p && ie_len) {
- pht_info = (struct HT_info_element *)(p+2);
-
- if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2))) {
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
+ pnetwork->IEs +
+ sizeof(struct ndis_802_11_fixed_ies),
+ pnetwork->IELength -
+ sizeof(struct ndis_802_11_fixed_ies));
+ if (p && p[1]) {
+ pht_info = (struct HT_info_element *)(p + 2);
+
+ if (pregpriv->cbw40_enable && pht_info->infos[0] & BIT(2)) {
/* switch to the 40M Hz mode */
cur_bwmode = HT_CHANNEL_WIDTH_40;
switch (pht_info->infos[0] & 0x3) {
case 1:
- /* pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; */
+ /* pmlmeext->cur_ch_offset =
+ HAL_PRIME_CHNL_OFFSET_LOWER; */
cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
break;
case 3:
update_wireless_mode23a(padapter);
/* udpate capability after cur_wireless_mode updated */
- update_capinfo23a(padapter, rtw_get_capability23a((struct wlan_bssid_ex *)pnetwork));
+ update_capinfo23a(padapter, rtw_get_capability23a(pnetwork));
/* let pnetwork_mlmeext == pnetwork_mlme. */
memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
-#ifdef CONFIG_8723AU_P2P
- memcpy(pwdinfo->p2p_group_ssid, pnetwork->Ssid.ssid,
- pnetwork->Ssid.ssid_len);
- pwdinfo->p2p_group_ssid_len = pnetwork->Ssid.ssid_len;
-#endif /* CONFIG_8723AU_P2P */
-
if (pmlmeext->bstart_bss) {
- update_beacon23a(padapter, _TIM_IE_, NULL, false);
+ update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
/* issue beacon frame */
if (send_beacon23a(padapter) == _FAIL)
update_bmc_sta(padapter);
}
-int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf, int len)
+int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf,
+ unsigned int len)
{
int ret = _SUCCESS;
u8 *p;
u8 *pHT_caps_ie = NULL;
u8 *pHT_info_ie = NULL;
struct sta_info *psta = NULL;
+ __le16 *pbeacon;
u16 cap, 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 OUI1[] = {0x00, 0x50, 0xf2, 0x01};
u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
struct registry_priv *pregistrypriv = &padapter->registrypriv;
struct security_priv *psecuritypriv = &padapter->securitypriv;
if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
return _FAIL;
- if (len>MAX_IE_SZ)
+ if (len > MAX_IE_SZ)
return _FAIL;
pbss_network->IELength = len;
/* beacon interval */
/* ie + 8; 8: TimeStamp, 2: Beacon Interval 2:Capability */
- p = rtw_get_beacon_interval23a_from_ie(ie);
- pbss_network->Configuration.BeaconPeriod = get_unaligned_le16(p);
+ pbeacon = rtw_get_beacon_interval23a_from_ie(ie);
+ pbss_network->Configuration.BeaconPeriod = get_unaligned_le16(pbeacon);
/* capability */
cap = get_unaligned_le16(ie);
/* SSID */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len,
+ p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_SSID, &ie_len,
(pbss_network->IELength -_BEACON_IE_OFFSET_));
if (p && ie_len > 0) {
memset(&pbss_network->Ssid, 0, sizeof(struct cfg80211_ssid));
/* chnnel */
channel = 0;
pbss_network->Configuration.Length = 0;
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len,
+ p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_DS_PARAMS, &ie_len,
(pbss_network->IELength - _BEACON_IE_OFFSET_));
if (p && ie_len > 0)
channel = *(p + 2);
memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
/* get supported rates */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len,
+ p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_SUPP_RATES, &ie_len,
(pbss_network->IELength - _BEACON_IE_OFFSET_));
if (p) {
memcpy(supportRate, p+2, ie_len);
}
/* get ext_supported rates */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_,
+ p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_EXT_SUPP_RATES,
&ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_);
if (p) {
memcpy(supportRate+supportRateNum, p+2, ie_len);
rtw_set_supported_rate23a(pbss_network->SupportedRates, network_type);
/* parsing ERP_IE */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len,
+ p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_ERP_INFO, &ie_len,
(pbss_network->IELength - _BEACON_IE_OFFSET_));
if (p && ie_len > 0)
ERP_IE_handler23a(padapter, (struct ndis_802_11_var_ies *)p);
group_cipher = 0; pairwise_cipher = 0;
psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len,
+ p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_RSN, &ie_len,
(pbss_network->IELength - _BEACON_IE_OFFSET_));
if (p && ie_len > 0) {
if (rtw_parse_wpa2_ie23a(p, ie_len+2, &group_cipher,
psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2)) {
- p = rtw_get_ie23a(p, _SSN_IE_1_, &ie_len,
+ p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
(pbss_network->IELength - _BEACON_IE_OFFSET_ -
(ie_len + 2)));
- if ((p) && (!memcmp(p+2, OUI1, 4))) {
+ 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;
pmlmepriv->qospriv.qos_option = 0;
if (pregistrypriv->wmm_enable) {
for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2)) {
- p = rtw_get_ie23a(p, _VENDOR_SPECIFIC_IE_, &ie_len,
+ p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
(pbss_network->IELength -
_BEACON_IE_OFFSET_ - (ie_len + 2)));
if ((p) && !memcmp(p+2, WMM_PARA_IE, 6)) {
}
}
/* parsing HT_CAP_IE */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len,
+ p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_HT_CAPABILITY, &ie_len,
(pbss_network->IELength - _BEACON_IE_OFFSET_));
if (p && ie_len > 0) {
u8 rf_type;
ht_cap = true;
network_type |= WIRELESS_11_24N;
- rtw23a_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+ rf_type = rtl8723a_get_rf_type(padapter);
if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
(psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
}
/* parsing HT_INFO_IE */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len,
+ p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_HT_OPERATION, &ie_len,
(pbss_network->IELength - _BEACON_IE_OFFSET_));
if (p && ie_len > 0)
pHT_info_ie = p;
HT_info_handler23a(padapter, (struct ndis_802_11_var_ies *)pHT_info_ie);
}
- pbss_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pbss_network);
+ pbss_network->Length = get_wlan_bssid_ex_sz(pbss_network);
/* issue beacon to start bss network */
start_bss_network(padapter, (u8*)pbss_network);
return;
/* parsing ERP_IE */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_ERP_INFO, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
if (p && len>0)
{
struct ndis_802_11_var_ies * pIE = (struct ndis_802_11_var_ies *)p;
{
DBG_8723A("%s\n", __func__);
- if (!memcmp(RTW_WPA_OUI23A, oui, 4))
- {
+ 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)
switch (ie_id)
{
- case 0xFF:
-
- update_bcn_fixed_ie(padapter);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */
-
- break;
-
- case _TIM_IE_:
-
- update_BCNTIM(padapter);
-
- break;
-
- case _ERPINFO_IE_:
-
- update_bcn_erpinfo_ie(padapter);
-
- break;
-
- case _HT_CAPABILITY_IE_:
-
- update_bcn_htcap_ie(padapter);
-
- break;
-
- case _RSN_IE_2_:
-
- update_bcn_rsn_ie(padapter);
-
- break;
+ case 0xFF:
+ /* 8: TimeStamp, 2: Beacon Interval 2:Capability */
+ update_bcn_fixed_ie(padapter);
+ break;
- case _HT_ADD_INFO_IE_:
+ case WLAN_EID_TIM:
+ update_BCNTIM(padapter);
+ break;
- update_bcn_htinfo_ie(padapter);
+ case WLAN_EID_ERP_INFO:
+ update_bcn_erpinfo_ie(padapter);
+ break;
- break;
+ case WLAN_EID_HT_CAPABILITY:
+ update_bcn_htcap_ie(padapter);
+ break;
- case _VENDOR_SPECIFIC_IE_:
+ case WLAN_EID_RSN:
+ update_bcn_rsn_ie(padapter);
+ break;
- update_bcn_vendor_spec_ie(padapter, oui);
+ case WLAN_EID_HT_OPERATION:
+ update_bcn_htinfo_ie(padapter);
+ break;
- break;
+ case WLAN_EID_VENDOR_SPECIFIC:
+ update_bcn_vendor_spec_ie(padapter, oui);
+ break;
- default:
- break;
+ default:
+ break;
}
pmlmepriv->update_bcn = true;
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_20_40)
- && pmlmepriv->num_sta_ht_20mhz)
+ 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 = OP_MODE_20MHZ_HT_STA_ASSOCED;
else if (pmlmepriv->olbc_ht)
new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
if (pmlmepriv->num_sta_non_erp == 1)
{
beacon_updated = true;
- update_beacon23a(padapter, _ERPINFO_IE_, NULL, true);
+ update_beacon23a(padapter, WLAN_EID_ERP_INFO, NULL, true);
}
}
if (pmlmepriv->num_sta_non_erp == 0)
{
beacon_updated = true;
- update_beacon23a(padapter, _ERPINFO_IE_, NULL, true);
+ update_beacon23a(padapter, WLAN_EID_ERP_INFO, NULL, true);
}
}
if (rtw_ht_operation_update(padapter) > 0)
{
- update_beacon23a(padapter, _HT_CAPABILITY_IE_, NULL, false);
- update_beacon23a(padapter, _HT_ADD_INFO_IE_, NULL, true);
+ update_beacon23a(padapter, WLAN_EID_HT_CAPABILITY, NULL, false);
+ update_beacon23a(padapter, WLAN_EID_HT_OPERATION, NULL, true);
}
/* update associcated stations cap. */
if (pmlmepriv->num_sta_non_erp == 0)
{
beacon_updated = true;
- update_beacon23a(padapter, _ERPINFO_IE_, NULL, true);
+ update_beacon23a(padapter, WLAN_EID_ERP_INFO,
+ NULL, true);
}
}
if (rtw_ht_operation_update(padapter) > 0)
{
- update_beacon23a(padapter, _HT_CAPABILITY_IE_, NULL, false);
- update_beacon23a(padapter, _HT_ADD_INFO_IE_, NULL, true);
+ update_beacon23a(padapter, WLAN_EID_HT_CAPABILITY, NULL, false);
+ update_beacon23a(padapter, WLAN_EID_HT_OPERATION, NULL, true);
}
/* update associcated stations cap. */
#include <osdep_service.h>
#include <drv_types.h>
#include <recv_osdep.h>
-#include <cmd_osdep.h>
#include <mlme_osdep.h>
+#include <rtl8723a_cmd.h>
#ifdef CONFIG_8723AU_BT_COEXIST
#include <rtl8723a_hal.h>
{
int res = _SUCCESS;
- sema_init(&pcmdpriv->cmd_queue_sema, 0);
- sema_init(&pcmdpriv->terminate_cmdthread_sema, 0);
-
- _rtw_init_queue23a(&pcmdpriv->cmd_queue);
-
- pcmdpriv->cmd_seq = 1;
-
pcmdpriv->cmd_allocated_buf = kzalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ,
GFP_KERNEL);
pcmdpriv->cmd_done_cnt = 0;
pcmdpriv->rsp_cnt = 0;
+
+ pcmdpriv->wq = alloc_workqueue("rtl8723au", 0, 1);
+ if (!pcmdpriv->wq)
+ res = _FAIL;
+
exit:
return res;
/* forward definition */
static void c2h_wk_callback(struct work_struct *work);
-int _rtw_init_evt_priv23a(struct evt_priv *pevtpriv)
-{
- int res = _SUCCESS;
+u32 rtw_init_evt_priv23a(struct evt_priv *pevtpriv)
+{
/* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
atomic_set(&pevtpriv->event_seq, 0);
pevtpriv->evt_done_cnt = 0;
pevtpriv->c2h_wk_alive = false;
pevtpriv->c2h_queue = rtw_cbuf_alloc23a(C2H_QUEUE_MAX_LEN + 1);
- return res;
+ return _SUCCESS;
}
-void _rtw_free_evt_priv23a (struct evt_priv *pevtpriv)
+void rtw_free_evt_priv23a(struct evt_priv *pevtpriv)
{
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
- ("+_rtw_free_evt_priv23a\n"));
cancel_work_sync(&pevtpriv->c2h_wk);
- while(pevtpriv->c2h_wk_alive)
+ while (pevtpriv->c2h_wk_alive)
msleep(10);
while (!rtw_cbuf_empty23a(pevtpriv->c2h_queue)) {
kfree(c2h);
}
}
-
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
- ("-_rtw_free_evt_priv23a\n"));
}
-void _rtw_free_cmd_priv23a(struct cmd_priv *pcmdpriv)
+void rtw_free_cmd_priv23a(struct cmd_priv *pcmdpriv)
{
+ RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
+ ("rtw_free_cmd_priv23a\n"));
+
if (pcmdpriv) {
kfree(pcmdpriv->cmd_allocated_buf);
kfree(pcmdpriv->rsp_allocated_buf);
}
}
-/*
-Calling Context:
-rtw_enqueue_cmd23a can only be called between kernel thread,
-since only spin_lock is used.
-
-ISR/Call-Back functions can't call this sub-function.
-*/
-
-int _rtw_enqueue_cmd23a(struct rtw_queue *queue, struct cmd_obj *obj)
-{
- unsigned long irqL;
-
- if (obj == NULL)
- goto exit;
-
- spin_lock_irqsave(&queue->lock, irqL);
-
- list_add_tail(&obj->list, &queue->queue);
-
- spin_unlock_irqrestore(&queue->lock, irqL);
-
-exit:
-
- return _SUCCESS;
-}
-
-u32 rtw_init_evt_priv23a(struct evt_priv *pevtpriv)
-{
- int res;
-
- res = _rtw_init_evt_priv23a(pevtpriv);
-
- return res;
-}
-
-void rtw_free_evt_priv23a(struct evt_priv *pevtpriv)
-{
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
- ("rtw_free_evt_priv23a\n"));
- _rtw_free_evt_priv23a(pevtpriv);
-}
-
-void rtw_free_cmd_priv23a(struct cmd_priv *pcmdpriv)
-{
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
- ("rtw_free_cmd_priv23a\n"));
- _rtw_free_cmd_priv23a(pcmdpriv);
-}
-
static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
{
struct drvextra_cmd_parm *pdrvextra_cmd_parm;
if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan))
bAllow = true;
- if ((pcmdpriv->padapter->hw_init_completed == false &&
- bAllow == false) || pcmdpriv->cmdthd_running == false)
+ if (pcmdpriv->padapter->hw_init_completed == false && bAllow == false)
return _FAIL;
return _SUCCESS;
}
-u32 rtw_enqueue_cmd23a(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
+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;
- struct rtw_adapter *padapter = pcmdpriv->padapter;
if (!cmd_obj)
goto exit;
- cmd_obj->padapter = padapter;
+ cmd_obj->padapter = pcmdpriv->padapter;
res = rtw_cmd_filter(pcmdpriv, cmd_obj);
if (res == _FAIL) {
goto exit;
}
- res = _rtw_enqueue_cmd23a(&pcmdpriv->cmd_queue, cmd_obj);
+ INIT_WORK(&cmd_obj->work, rtw_cmd_work);
- if (res == _SUCCESS)
- up(&pcmdpriv->cmd_queue_sema);
+ res = queue_work(pcmdpriv->wq, &cmd_obj->work);
+ if (!res) {
+ printk(KERN_ERR "%s: Call to queue_work() failed\n", __func__);
+ res = _FAIL;
+ } else
+ res = _SUCCESS;
exit:
- return res;
-}
-
-static struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv)
-{
- struct cmd_obj *obj;
- struct rtw_queue *queue = &pcmdpriv->cmd_queue;
- unsigned long irqL;
-
- spin_lock_irqsave(&queue->lock, irqL);
- if (list_empty(&queue->queue))
- obj = NULL;
- else {
- obj = container_of((&queue->queue)->next, struct cmd_obj, list);
- list_del_init(&obj->list);
- }
-
- spin_unlock_irqrestore(&queue->lock, irqL);
- return obj;
+ return res;
}
void rtw_cmd_clr_isr23a(struct cmd_priv *pcmdpriv)
kfree(pcmd);
}
-int rtw_cmd_thread23a(void *context)
+static void rtw_cmd_work(struct work_struct *work)
{
- u8 ret;
- struct cmd_obj *pcmd;
- u8 *pcmdbuf, *prspbuf;
- u8 (*cmd_hdl)(struct rtw_adapter *padapter, u8* pbuf);
+ u8 (*cmd_hdl)(struct rtw_adapter *padapter, const u8 *pbuf);
void (*pcmd_callback)(struct rtw_adapter *dev, struct cmd_obj *pcmd);
- struct rtw_adapter *padapter = (struct rtw_adapter *)context;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
- allow_signal(SIGTERM);
+ struct cmd_priv *pcmdpriv;
+ struct cmd_obj *pcmd = container_of(work, struct cmd_obj, work);
+ u8 *pcmdbuf;
+ pcmdpriv = &pcmd->padapter->cmdpriv;
pcmdbuf = pcmdpriv->cmd_buf;
- prspbuf = pcmdpriv->rsp_buf;
-
- pcmdpriv->cmdthd_running = true;
- up(&pcmdpriv->terminate_cmdthread_sema);
-
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
- ("start r871x rtw_cmd_thread23a !!!!\n"));
-
- while(1) {
- if (down_interruptible(&pcmdpriv->cmd_queue_sema))
- break;
-_next:
- if ((padapter->bDriverStopped == true) ||
- (padapter->bSurpriseRemoved == true)) {
- DBG_8723A("%s: DriverStopped(%d) SurpriseRemoved(%d) "
- "break at line %d\n", __func__,
- padapter->bDriverStopped,
- padapter->bSurpriseRemoved, __LINE__);
- break;
- }
- if (!(pcmd = rtw_dequeue_cmd(pcmdpriv)))
- continue;
-
- 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 (rtw_cmd_filter(pcmdpriv, pcmd) == _FAIL) {
+ pcmd->res = H2C_DROPPED;
+ goto post_process;
+ }
- memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
+ pcmdpriv->cmd_issued_cnt++;
- if (pcmd->cmdcode < (sizeof(wlancmds)/sizeof(struct cmd_hdl))) {
- cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
+ pcmd->cmdsz = ALIGN(pcmd->cmdsz, 4);
- if (cmd_hdl) {
- ret = cmd_hdl(pcmd->padapter, pcmdbuf);
- pcmd->res = ret;
- }
+ memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
- pcmdpriv->cmd_seq++;
- } else
- pcmd->res = H2C_PARAMETERS_ERROR;
+ if (pcmd->cmdcode < (sizeof(wlancmds)/sizeof(struct cmd_hdl))) {
+ cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
- cmd_hdl = NULL;
+ if (cmd_hdl)
+ pcmd->res = cmd_hdl(pcmd->padapter, pcmdbuf);
+ else
+ pcmd->res = H2C_DROPPED;
+ } else
+ pcmd->res = H2C_PARAMETERS_ERROR;
post_process:
- /* call callback function for post-processed */
- if (pcmd->cmdcode < (sizeof(rtw_cmd_callback) /
- sizeof(struct _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 {
- /* todo: !!! fill rsp_buf to pcmd->rsp
- if (pcmd->rsp!= NULL) */
- /* need conider 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));
+ /* call callback function for post-processed */
+ if (pcmd->cmdcode < (sizeof(rtw_cmd_callback) /
+ sizeof(struct _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 {
+ /* todo: !!! fill rsp_buf to pcmd->rsp
+ if (pcmd->rsp!= NULL) */
+ /* need conider that free cmd_obj in
+ rtw_cmd_callback */
+ pcmd_callback(pcmd->padapter, pcmd);
}
-
- if (signal_pending (current))
- flush_signals(current);
-
- goto _next;
-
- }
- pcmdpriv->cmdthd_running = false;
-
- /* free all cmd_obj resources */
- do {
- pcmd = rtw_dequeue_cmd(pcmdpriv);
- if (!pcmd)
- break;
-
+ } 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);
- } while(1);
-
- up(&pcmdpriv->terminate_cmdthread_sema);
-
- complete_and_exit(NULL, 0);
+ }
}
+
u8 rtw_sitesurvey_cmd23a(struct rtw_adapter *padapter,
struct cfg80211_ssid *ssid, int ssid_num,
struct rtw_ieee80211_channel *ch, int ch_num)
if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_SCAN, 1);
-#ifdef CONFIG_8723AU_P2P
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
- p2p_ps_wk_cmd23a(padapter, P2P_PS_SCAN, 1);
- }
-#endif /* CONFIG_8723AU_P2P */
-
ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (!ph2c)
return _FAIL;
return _FAIL;
}
- rtw_free_network_queue23a(padapter, false);
+ rtw_free_network_queue23a(padapter);
RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
("%s: flush network queue\n", __func__));
goto exit;
}
- INIT_LIST_HEAD(&pcmd->list);
pcmd->cmdcode = _CreateBss_CMD_;
pcmd->parmbuf = (unsigned char *)pdev_network;
- pcmd->cmdsz = get_wlan_bssid_ex_sz((struct wlan_bssid_ex*)pdev_network);
+ pcmd->cmdsz = get_wlan_bssid_ex_sz(pdev_network);
pcmd->rsp = NULL;
pcmd->rspsz = 0;
}
u8 rtw_joinbss_cmd23a(struct rtw_adapter *padapter,
- struct wlan_network * pnetwork)
+ struct wlan_network *pnetwork)
{
u8 *auth, res = _SUCCESS;
- uint t_len = 0;
struct wlan_bssid_ex *psecnetwork;
struct cmd_obj *pcmd;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
"fail!!!\n"));
goto exit;
}
- /* for IEs is fix buf size */
- t_len = sizeof(struct wlan_bssid_ex);
/* for hidden ap to set fw_state here */
if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE)) {
}
}
- psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss;
+ psecnetwork = &psecuritypriv->sec_bss;
if (!psecnetwork) {
if (pcmd)
kfree(pcmd);
goto exit;
}
- memset(psecnetwork, 0, t_len);
+ memset(psecnetwork, 0, sizeof(struct wlan_bssid_ex));
memcpy(psecnetwork, &pnetwork->network,
get_wlan_bssid_ex_sz(&pnetwork->network));
/* get cmdsz before endian conversion */
pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);
- INIT_LIST_HEAD(&pcmd->list);
pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */
pcmd->parmbuf = (unsigned char *)psecnetwork;
pcmd->rsp = NULL;
pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic;
}
-void dynamic_chk_wk_hdl(struct rtw_adapter *padapter, u8 *pbuf, int sz)
+static void dynamic_chk_wk_hdl(struct rtw_adapter *padapter, u8 *pbuf, int sz)
{
struct mlme_priv *pmlmepriv;
#endif
}
-void lps_ctrl_wk_hdl(struct rtw_adapter *padapter, u8 lps_ctrl_type)
+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;
mstatus = 1;/* connect */
/* Reset LPS Setting */
padapter->pwrctrlpriv.LpsIdleCount = 0;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
- (u8 *)&mstatus);
+ rtl8723a_set_FwJoinBssReport_cmd(padapter, 1);
#ifdef CONFIG_8723AU_BT_COEXIST
BT_WifiMediaStatusNotify(padapter, mstatus);
#endif
{
LPS_Leave23a(padapter);
}
- rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
- (u8 *)&mstatus);
+ rtl8723a_set_FwJoinBssReport_cmd(padapter, 0);
break;
case LPS_CTRL_SPECIAL_PACKET:
pwrpriv->DelayLPSLastTimeStamp = jiffies;
rtw_ps_processor23a(padapter);
}
-#ifdef CONFIG_8723AU_P2P
-u8 p2p_protocol_wk_cmd23a(struct rtw_adapter*padapter, int intCmdType)
-{
- struct cmd_obj *ph2c;
- struct drvextra_cmd_parm *pdrvextra_cmd_parm;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- {
- return res;
- }
-
- 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 = P2P_PROTO_WK_CID;
- pdrvextra_cmd_parm->type_size = intCmdType; /* As the command tppe. */
- pdrvextra_cmd_parm->pbuf = NULL; /* Must be NULL here */
-
- 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 /* CONFIG_8723AU_P2P */
-
u8 rtw_ps_cmd23a(struct rtw_adapter*padapter)
{
struct cmd_obj *ppscmd;
return;
if (psta_bmc->sleepq_len == 0) {
- u8 val = 0;
+ bool val;
- rtw23a_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &val);
+ val = rtl8723a_chk_hi_queue_empty(padapter);
- while(val == false) {
+ while (val == false) {
msleep(100);
cnt++;
if (cnt>10)
break;
- rtw23a_hal_get_hwreg(padapter,
- HW_VAR_CHK_HI_QUEUE_EMPTY, &val);
+ val = rtl8723a_chk_hi_queue_empty(padapter);
}
if (cnt <= 10) {
pstapriv->tim_bitmap &= ~BIT(0);
pstapriv->sta_dz_bitmap &= ~BIT(0);
- update_beacon23a(padapter, _TIM_IE_, NULL, false);
+ update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
} else /* re check again */
rtw_chk_hi_queue_cmd23a(padapter);
}
/* This C2H event is read, clear it */
c2h_evt_clear23a(adapter);
} else if ((c2h_evt = (struct c2h_evt_hdr *)
- kmalloc(16, GFP_ATOMIC))) {
+ kmalloc(16, GFP_KERNEL))) {
+ if (!c2h_evt)
+ continue;
/* This C2H event is not read, read & clear now */
if (c2h_evt_read23a(adapter, (u8*)c2h_evt) != _SUCCESS)
continue;
evtpriv->c2h_wk_alive = false;
}
-u8 rtw_drvextra_cmd_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
+u8 rtw_drvextra_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
- struct drvextra_cmd_parm *pdrvextra_cmd;
+ const struct drvextra_cmd_parm *pdrvextra_cmd;
if (!pbuf)
return H2C_PARAMETERS_ERROR;
case LPS_CTRL_WK_CID:
lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size);
break;
-#ifdef CONFIG_8723AU_P2P
- case P2P_PS_WK_CID:
- p2p_ps_wk_hdl23a(padapter, pdrvextra_cmd->type_size);
- break;
- case P2P_PROTO_WK_CID:
- /* Commented by Albert 2011/07/01 */
- /* I used the type_size as the type command */
- p2p_protocol_wk_hdl23a(padapter, pdrvextra_cmd->type_size);
- break;
-#endif /* CONFIG_8723AU_P2P */
#ifdef CONFIG_8723AU_AP_MODE
case CHECK_HIQ_WK_CID:
rtw_chk_hi_queue_hdl(padapter);
if (pdrvextra_cmd->pbuf && (pdrvextra_cmd->type_size > 0)) {
kfree(pdrvextra_cmd->pbuf);
- pdrvextra_cmd->pbuf = NULL;
+ /*
+ * 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;
exit:
rtw_free_cmd_obj23a(pcmd);
}
-
-void rtw_getrttbl_cmd_cmdrsp_callback(struct rtw_adapter *padapter,
- struct cmd_obj *pcmd)
-{
- rtw_free_cmd_obj23a(pcmd);
-}
}
/* rtw_set_ie23a will update frame length */
-u8 *rtw_set_ie23a(u8 *pbuf, int index, uint len, u8 *source, uint *frlen)
+u8 *rtw_set_ie23a(u8 *pbuf, int index, uint len, const u8 *source, uint *frlen)
{
*pbuf = (u8)index;
ie += 2;
/* SSID */
- ie = rtw_set_ie23a(ie, _SSID_IE_, pdev_network->Ssid.ssid_len,
+ ie = rtw_set_ie23a(ie, WLAN_EID_SSID, pdev_network->Ssid.ssid_len,
pdev_network->Ssid.ssid, &sz);
/* supported rates */
rateLen = rtw_get_rateset_len23a(pdev_network->SupportedRates);
if (rateLen > 8) {
- ie = rtw_set_ie23a(ie, _SUPPORTEDRATES_IE_, 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, _SUPPORTEDRATES_IE_, rateLen,
+ ie = rtw_set_ie23a(ie, WLAN_EID_SUPP_RATES, rateLen,
pdev_network->SupportedRates, &sz);
}
/* DS parameter set */
- ie = rtw_set_ie23a(ie, _DSSET_IE_, 1,
+ ie = rtw_set_ie23a(ie, WLAN_EID_DS_PARAMS, 1,
(u8 *)&pdev_network->Configuration.DSConfig, &sz);
/* IBSS Parameter Set */
- ie = rtw_set_ie23a(ie, _IBSS_PARA_IE_, 2,
+ ie = rtw_set_ie23a(ie, WLAN_EID_IBSS_PARAMS, 2,
(u8 *)&pdev_network->Configuration.ATIMWindow, &sz);
if (rateLen > 8) {
- ie = rtw_set_ie23a(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8),
+ ie = rtw_set_ie23a(ie, WLAN_EID_EXT_SUPP_RATES, (rateLen - 8),
(pdev_network->SupportedRates + 8), &sz);
}
return sz;
}
-unsigned char *rtw_get_wpa_ie23a(unsigned char *pie, int *wpa_ie_len, int limit)
-{
- int len;
- u16 val16;
- unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01};
- u8 *pbuf = pie;
- int limit_new = limit;
-
- while(1) {
- pbuf = rtw_get_ie23a(pbuf, _WPA_IE_ID_, &len, limit_new);
-
- if (pbuf) {
- /* check if oui matches... */
- if (memcmp((pbuf + 2), wpa_oui_type,
- sizeof(wpa_oui_type))) {
- goto check_next_ie;
- }
-
- /* check version... */
- memcpy((u8 *)&val16, (pbuf + 6), sizeof(val16));
-
- val16 = le16_to_cpu(val16);
- if (val16 != 0x0001)
- goto check_next_ie;
-
- *wpa_ie_len = *(pbuf + 1);
-
- return pbuf;
- } else {
- *wpa_ie_len = 0;
- return NULL;
- }
-
-check_next_ie:
-
- limit_new = limit - (pbuf - pie) - 2 - len;
-
- if (limit_new <= 0)
- break;
-
- pbuf += (2 + len);
- }
-
- *wpa_ie_len = 0;
-
- return NULL;
-}
-
-unsigned char *rtw_get_wpa2_ie23a(unsigned char *pie, int *rsn_ie_len, int limit)
-{
- return rtw_get_ie23a(pie, _WPA2_IE_ID_, rsn_ie_len, limit);
-}
-
-int rtw_get_wpa_cipher_suite23a(u8 *s)
+int rtw_get_wpa_cipher_suite23a(const u8 *s)
{
if (!memcmp(s, WPA_CIPHER_SUITE_NONE23A, WPA_SELECTOR_LEN))
return WPA_CIPHER_NONE;
return 0;
}
-int rtw_get_wpa2_cipher_suite23a(u8 *s)
+int rtw_get_wpa2_cipher_suite23a(const u8 *s)
{
if (!memcmp(s, RSN_CIPHER_SUITE_NONE23A, RSN_SELECTOR_LEN))
return WPA_CIPHER_NONE;
return 0;
}
-int rtw_parse_wpa_ie23a(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x)
+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;
- u8 *pos;
- u8 SUITE_1X[4] = {0x00, 0x50, 0xf2, 1};
+ const u8 *pos;
if (wpa_ie_len <= 0) {
/* No WPA IE - fail silently */
return _FAIL;
}
- if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie+1) != (u8)(wpa_ie_len - 2)) ||
- memcmp(wpa_ie + 2, RTW_WPA_OUI23A_TYPE, WPA_SELECTOR_LEN)) {
+ if (wpa_ie[1] != (u8)(wpa_ie_len - 2))
return _FAIL;
- }
pos = wpa_ie;
if (is_8021x) {
if (left >= 6) {
pos += 2;
- if (!memcmp(pos, SUITE_1X, 4)) {
+ if (!memcmp(pos, RTW_WPA_OUI23A_TYPE, 4)) {
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
("%s : there has 802.1x auth\n",
__func__));
return ret;
}
-int rtw_parse_wpa2_ie23a(u8* rsn_ie, int rsn_ie_len, int *group_cipher,
+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;
- u8 *pos;
+ const u8 *pos;
u8 SUITE_1X[4] = {0x00, 0x0f, 0xac, 0x01};
if (rsn_ie_len <= 0) {
u8 *wpa_ie, u16 *wpa_len)
{
u8 authmode, sec_idx, i;
- u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01};
uint cnt;
-
/* Search required WPA or WPA2 IE and copy to sec_ie[ ] */
cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);
while(cnt < in_len) {
authmode = in_ie[cnt];
- if ((authmode == _WPA_IE_ID_) &&
- !memcmp(&in_ie[cnt+2], &wpa_oui[0], 4)) {
+ if ((authmode == WLAN_EID_VENDOR_SPECIFIC) &&
+ !memcmp(&in_ie[cnt+2], RTW_WPA_OUI23A_TYPE, 4)) {
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
("\n rtw_get_wpa_ie23a: sec_idx =%d "
"in_ie[cnt+1]+2 =%d\n",
eid = ie_ptr[0];
- if ((eid == _WPA_IE_ID_) && !memcmp(&ie_ptr[2], wps_oui, 4)) {
+ if ((eid == WLAN_EID_VENDOR_SPECIFIC) &&
+ !memcmp(&ie_ptr[2], wps_oui, 4)) {
/* DBG_8723A("==> found WPS_IE.....\n"); */
*wps_ielen = ie_ptr[1] + 2;
match = true;
while (cnt < in_len) {
eid = in_ie[cnt];
- if ((eid == _WPA_IE_ID_) && !memcmp(&in_ie[cnt+2], wps_oui, 4)) {
+ if ((eid == WLAN_EID_VENDOR_SPECIFIC) &&
+ !memcmp(&in_ie[cnt+2], wps_oui, 4)) {
wpsie_ptr = &in_ie[cnt];
if (wps_ie)
if (len_attr)
*len_attr = 0;
- if ((wps_ie[0] != _VENDOR_SPECIFIC_IE_) ||
+ if ((wps_ie[0] != WLAN_EID_VENDOR_SPECIFIC) ||
memcmp(wps_ie + 2, wps_oui, 4)) {
return attr_ptr;
}
return NULL;
}
-static int
-rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen,
- struct rtw_ieee802_11_elems *elems,
- int show_errors)
-{
- 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) {
- if (show_errors) {
- DBG_8723A("short vendor specific "
- "information element ignored (len =%lu)\n",
- (unsigned long) elen);
- }
- return -1;
- }
-
- 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 1:
- /* Microsoft OUI (00:50:F2) with OUI Type 1:
- * real WPA information element */
- elems->wpa_ie = pos;
- elems->wpa_ie_len = elen;
- break;
- case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */
- if (elen < 5) {
- DBG_8723A("short WME "
- "information element ignored "
- "(len =%lu)\n",
- (unsigned long) elen);
- return -1;
- }
- switch (pos[4]) {
- case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
- case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
- elems->wme = pos;
- elems->wme_len = elen;
- break;
- case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
- elems->wme_tspec = pos;
- elems->wme_tspec_len = elen;
- break;
- default:
- DBG_8723A("unknown WME "
- "information element ignored "
- "(subtype =%d len =%lu)\n",
- pos[4], (unsigned long) elen);
- return -1;
- }
- break;
- case 4:
- /* Wi-Fi Protected Setup (WPS) IE */
- elems->wps_ie = pos;
- elems->wps_ie_len = elen;
- break;
- default:
- DBG_8723A("Unknown Microsoft "
- "information element ignored "
- "(type =%d len =%lu)\n",
- pos[3], (unsigned long) elen);
- return -1;
- }
- break;
-
- case OUI_BROADCOM:
- switch (pos[3]) {
- case VENDOR_HT_CAPAB_OUI_TYPE:
- elems->vendor_ht_cap = pos;
- elems->vendor_ht_cap_len = elen;
- break;
- default:
- DBG_8723A("Unknown Broadcom "
- "information element ignored "
- "(type =%d len =%lu)\n",
- pos[3], (unsigned long) elen);
- return -1;
- }
- break;
-
- default:
- DBG_8723A("unknown vendor specific information "
- "element ignored (vendor OUI %02x:%02x:%02x "
- "len =%lu)\n",
- pos[0], pos[1], pos[2], (unsigned long) elen);
- return -1;
- }
-
- return 0;
-}
-
-/**
- * ieee802_11_parse_elems - Parse information elements in management frames
- * @start: Pointer to the start of IEs
- * @len: Length of IE buffer in octets
- * @elems: Data structure for parsed elements
- * @show_errors: Whether to show parsing errors in debug log
- * Returns: Parsing result
- */
-enum parse_res rtw_ieee802_11_parse_elems23a(u8 *start, uint len,
- struct rtw_ieee802_11_elems *elems,
- int show_errors)
-{
- uint left = len;
- u8 *pos = start;
- int unknown = 0;
-
- memset(elems, 0, sizeof(*elems));
-
- while (left >= 2) {
- u8 id, elen;
-
- id = *pos++;
- elen = *pos++;
- left -= 2;
-
- if (elen > left) {
- if (show_errors) {
- DBG_8723A("IEEE 802.11 element "
- "parse failed (id =%d elen =%d "
- "left =%lu)\n",
- id, elen, (unsigned long) left);
- }
- return ParseFailed;
- }
-
- switch (id) {
- case WLAN_EID_SSID:
- elems->ssid = pos;
- elems->ssid_len = elen;
- break;
- case WLAN_EID_SUPP_RATES:
- elems->supp_rates = pos;
- elems->supp_rates_len = elen;
- break;
- case WLAN_EID_FH_PARAMS:
- elems->fh_params = pos;
- elems->fh_params_len = elen;
- break;
- case WLAN_EID_DS_PARAMS:
- elems->ds_params = pos;
- elems->ds_params_len = elen;
- break;
- case WLAN_EID_CF_PARAMS:
- elems->cf_params = pos;
- elems->cf_params_len = elen;
- break;
- case WLAN_EID_TIM:
- elems->tim = pos;
- elems->tim_len = elen;
- break;
- case WLAN_EID_IBSS_PARAMS:
- elems->ibss_params = pos;
- elems->ibss_params_len = elen;
- break;
- case WLAN_EID_CHALLENGE:
- elems->challenge = pos;
- elems->challenge_len = elen;
- break;
- case WLAN_EID_ERP_INFO:
- elems->erp_info = pos;
- elems->erp_info_len = elen;
- break;
- case WLAN_EID_EXT_SUPP_RATES:
- elems->ext_supp_rates = pos;
- elems->ext_supp_rates_len = elen;
- break;
- case WLAN_EID_VENDOR_SPECIFIC:
- if (rtw_ieee802_11_parse_vendor_specific(pos, elen,
- elems,
- show_errors))
- unknown++;
- break;
- case WLAN_EID_RSN:
- elems->rsn_ie = pos;
- elems->rsn_ie_len = elen;
- break;
- case WLAN_EID_PWR_CAPABILITY:
- elems->power_cap = pos;
- elems->power_cap_len = elen;
- break;
- case WLAN_EID_SUPPORTED_CHANNELS:
- elems->supp_channels = pos;
- elems->supp_channels_len = elen;
- break;
- case WLAN_EID_MOBILITY_DOMAIN:
- elems->mdie = pos;
- elems->mdie_len = elen;
- break;
- case WLAN_EID_FAST_BSS_TRANSITION:
- elems->ftie = pos;
- elems->ftie_len = elen;
- break;
- case WLAN_EID_TIMEOUT_INTERVAL:
- elems->timeout_int = pos;
- elems->timeout_int_len = elen;
- break;
- case WLAN_EID_HT_CAPABILITY:
- elems->ht_capabilities = pos;
- elems->ht_capabilities_len = elen;
- break;
- case WLAN_EID_HT_OPERATION:
- elems->ht_operation = pos;
- elems->ht_operation_len = elen;
- break;
- default:
- unknown++;
- if (!show_errors)
- break;
- DBG_8723A("IEEE 802.11 element parse "
- "ignored unknown element (id =%d elen =%d)\n",
- id, elen);
- break;
- }
-
- left -= elen;
- pos += elen;
- }
-
- if (left)
- return ParseFailed;
-
- return unknown ? ParseUnknown : ParseOK;
-}
-
static u8 key_char2num(u8 ch)
{
if ((ch >= '0') && (ch <= '9'))
MAC_ARG(mac_addr));
}
-void dump_ies23a(u8 *buf, u32 buf_len) {
- u8* pos = (u8*)buf;
- u8 id, len;
-
- while (pos-buf <= buf_len) {
- id = *pos;
- len = *(pos + 1);
-
- DBG_8723A("%s ID:%u, LEN:%u\n", __func__, id, len);
-#ifdef CONFIG_8723AU_P2P
- dump_p2p_ie23a(pos, len);
-#endif
- dump_wps_ie23a(pos, len);
-
- pos += (2 + len);
- }
-}
-
-void dump_wps_ie23a(u8 *ie, u32 ie_len) {
- u8* pos = (u8*)ie;
- u16 id;
- u16 len;
-
- u8 *wps_ie;
- uint wps_ielen;
-
- wps_ie = rtw_get_wps_ie23a(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_8723A("%s ID:0x%04x, LEN:%u\n", __func__, id, len);
-
- pos += (4 + len);
- }
-}
-
-#ifdef CONFIG_8723AU_P2P
-void dump_p2p_ie23a(u8 *ie, u32 ie_len) {
- u8* pos = (u8*)ie;
- u8 id;
- u16 len;
-
- u8 *p2p_ie;
- uint p2p_ielen;
-
- p2p_ie = rtw_get_p2p_ie23a(ie, ie_len, NULL, &p2p_ielen);
- if (p2p_ie != ie || p2p_ielen == 0)
- return;
-
- pos += 6;
- while (pos-ie < ie_len) {
- id = *pos;
- len = get_unaligned_le16(pos+1);
-
- DBG_8723A("%s ID:%u, LEN:%u\n", __func__, id, len);
-
- pos+= (3+len);
- }
-}
-
-/**
- * rtw_get_p2p_ie23a - Search P2P IE from a series of IEs
- * @in_ie: Address of IEs to search
- * @in_len: Length limit from in_ie
- * @p2p_ie: If not NULL and P2P IE is found, P2P IE will be copied to the
- * buf starting from p2p_ie
- * @p2p_ielen: If not NULL and P2P IE is found, will set to the length of
- * the entire P2P IE
- *
- * Returns: The address of the P2P IE found, or NULL
- */
-u8 *rtw_get_p2p_ie23a(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen)
-{
- uint cnt = 0;
- u8 *p2p_ie_ptr;
- u8 eid, p2p_oui[4]={0x50, 0x6F, 0x9A, 0x09};
-
- if (p2p_ielen)
- *p2p_ielen = 0;
-
- while (cnt<in_len) {
- eid = in_ie[cnt];
- if ((in_len < 0) || (cnt > MAX_IE_SZ)) {
- dump_stack();
- return NULL;
- }
- if ((eid == _VENDOR_SPECIFIC_IE_) &&
- !memcmp(&in_ie[cnt + 2], p2p_oui, 4)) {
- p2p_ie_ptr = in_ie + cnt;
-
- if (p2p_ie != NULL) {
- memcpy(p2p_ie, &in_ie[cnt],
- in_ie[cnt + 1] + 2);
- }
-
- if (p2p_ielen != NULL) {
- *p2p_ielen = in_ie[cnt + 1] + 2;
- }
-
- return p2p_ie_ptr;
-
- break;
- } else {
- cnt += in_ie[cnt + 1] + 2; /* goto next */
- }
- }
-
- return NULL;
-}
-
-/**
- * rtw_get_p2p_attr23a - Search a specific P2P attribute from a given P2P IE
- * @p2p_ie: Address of P2P IE to search
- * @p2p_ielen: Length limit from p2p_ie
- * @target_attr_id: The attribute ID of P2P attribute to search
- * @buf_attr: If not NULL and the P2P attribute is found, P2P attribute will
- * be copied to the buf starting from buf_attr
- * @len_attr: If not NULL and the P2P attribute is found, will set to the
- * length of the entire P2P attribute
- *
- * Returns: the address of the specific WPS attribute found, or NULL
- */
-u8 *rtw_get_p2p_attr23a(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id,
- u8 *buf_attr, u32 *len_attr)
-{
- u8 *attr_ptr = NULL;
- u8 *target_attr_ptr = NULL;
- u8 p2p_oui[4]={0x50, 0x6F, 0x9A, 0x09};
-
- if (len_attr)
- *len_attr = 0;
-
- if (!p2p_ie || (p2p_ie[0] != _VENDOR_SPECIFIC_IE_) ||
- memcmp(p2p_ie + 2, p2p_oui, 4)) {
- return attr_ptr;
- }
-
- /* 6 = 1(Element ID) + 1(Length) + 3 (OUI) + 1(OUI Type) */
- attr_ptr = p2p_ie + 6; /* goto first attr */
-
- while (attr_ptr - p2p_ie < p2p_ielen) {
- /* 3 = 1(Attribute ID) + 2(Length) */
- u8 attr_id = *attr_ptr;
- u16 attr_data_len = get_unaligned_le16(attr_ptr + 1);
- u16 attr_len = attr_data_len + 3;
-
- /* 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_p2p_attr23a_content - Search a specific P2P attribute content from
- * a given P2P IE
- * @p2p_ie: Address of P2P IE to search
- * @p2p_ielen: Length limit from p2p_ie
- * @target_attr_id: The attribute ID of P2P attribute to search
- * @buf_content: If not NULL and the P2P attribute is found, P2P attribute
- * content will be copied to the buf starting from buf_content
- * @len_content: If not NULL and the P2P attribute is found, will set to the
- * length of the P2P attribute content
- *
- * Returns: the address of the specific P2P attribute content found, or NULL
- */
-u8 *rtw_get_p2p_attr23a_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id,
- u8 *buf_content, uint *len_content)
-{
- u8 *attr_ptr;
- u32 attr_len;
-
- if (len_content)
- *len_content = 0;
-
- attr_ptr = rtw_get_p2p_attr23a(p2p_ie, p2p_ielen, target_attr_id,
- NULL, &attr_len);
-
- if (attr_ptr && attr_len) {
- if (buf_content)
- memcpy(buf_content, attr_ptr + 3, attr_len - 3);
-
- if (len_content)
- *len_content = attr_len - 3;
-
- return attr_ptr+3;
- }
-
- return NULL;
-}
-
-u32 rtw_set_p2p_attr_content23a(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr)
-{
- u32 a_len;
-
- *pbuf = attr_id;
-
- /* u16*)(pbuf + 1) = cpu_to_le16(attr_len); */
- put_unaligned_le16(attr_len, pbuf + 1);
-
- if (pdata_attr)
- memcpy(pbuf + 3, pdata_attr, attr_len);
-
- a_len = attr_len + 3;
-
- return a_len;
-}
-
-static uint rtw_p2p_attr_remove(u8 *ie, uint ielen_ori, u8 attr_id)
-{
- u8 *target_attr;
- u32 target_attr_len;
- uint ielen = ielen_ori;
-
- while(1) {
- target_attr = rtw_get_p2p_attr23a(ie, ielen, attr_id, NULL,
- &target_attr_len);
- if (target_attr && target_attr_len) {
- u8 *next_attr = target_attr+target_attr_len;
- uint remain_len = ielen-(next_attr-ie);
- /* dump_ies23a(ie, ielen); */
-
- memset(target_attr, 0, target_attr_len);
- memcpy(target_attr, next_attr, remain_len);
- memset(target_attr+remain_len, 0, target_attr_len);
- *(ie + 1) -= target_attr_len;
- ielen -= target_attr_len;
- } else {
- /* if (index>0) */
- /* dump_ies23a(ie, ielen); */
- break;
- }
- }
-
- return ielen;
-}
-
-void rtw_wlan_bssid_ex_remove_p2p_attr23a(struct wlan_bssid_ex *bss_ex, u8 attr_id)
-{
- u8 *p2p_ie;
- uint p2p_ielen, p2p_ielen_ori;
-
- if ((p2p_ie = rtw_get_p2p_ie23a(bss_ex->IEs + _FIXED_IE_LENGTH_,
- bss_ex->IELength - _FIXED_IE_LENGTH_,
- NULL, &p2p_ielen_ori))) {
- p2p_ielen = rtw_p2p_attr_remove(p2p_ie, p2p_ielen_ori, attr_id);
- if (p2p_ielen != p2p_ielen_ori) {
- u8 *next_ie_ori = p2p_ie+p2p_ielen_ori;
- u8 *next_ie = p2p_ie+p2p_ielen;
- uint remain_len;
- remain_len = bss_ex->IELength-(next_ie_ori-bss_ex->IEs);
-
- memcpy(next_ie, next_ie_ori, remain_len);
- memset(next_ie+remain_len, 0, p2p_ielen_ori-p2p_ielen);
- bss_ex->IELength -= p2p_ielen_ori-p2p_ielen;
- }
- }
-}
-
-#endif /* CONFIG_8723AU_P2P */
-
-#ifdef CONFIG_8723AU_P2P
-int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen)
-{
- int match;
- uint cnt = 0;
- u8 eid, wfd_oui[4] = {0x50, 0x6F, 0x9A, 0x0A};
-
- match = false;
-
- if (in_len < 0) {
- return match;
- }
-
- while (cnt < in_len)
- {
- eid = in_ie[cnt];
-
- if ((eid == _VENDOR_SPECIFIC_IE_) &&
- !memcmp(&in_ie[cnt+2], wfd_oui, 4)) {
- if (wfd_ie != NULL) {
- memcpy(wfd_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
-
- } else {
- if (wfd_ielen != NULL) {
- *wfd_ielen = 0;
- }
- }
-
- if (wfd_ielen != NULL) {
- *wfd_ielen = in_ie[cnt + 1] + 2;
- }
-
- cnt += in_ie[cnt + 1] + 2;
-
- match = true;
- break;
- } else {
- cnt += in_ie[cnt + 1] +2; /* goto next */
- }
- }
-
- if (match == true) {
- match = cnt;
- }
-
- return match;
-}
-
-/* attr_content: The output buffer, contains the "body field" of
- WFD attribute. */
-/* attr_contentlen: The data length of the "body field" of WFD
- attribute. */
-int rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id,
- u8 *attr_content, uint *attr_contentlen)
-{
- int match;
- uint cnt = 0;
- u8 attr_id, wfd_oui[4] = {0x50, 0x6F, 0x9A, 0x0A};
-
- match = false;
-
- if ((wfd_ie[0] != _VENDOR_SPECIFIC_IE_) ||
- memcmp(wfd_ie + 2, wfd_oui, 4)) {
- return match;
- }
-
- /* 1 (WFD IE) + 1 (Length) + 3 (OUI) + 1 (OUI Type) */
- cnt = 6;
- while (cnt < wfd_ielen) {
- u16 attrlen = get_unaligned_be16(wfd_ie + cnt + 1);
-
- attr_id = wfd_ie[cnt];
- if (attr_id == target_attr_id) {
- /* 3 -> 1 byte for attribute ID field, 2
- bytes for length field */
- if (attr_content)
- memcpy(attr_content, &wfd_ie[cnt + 3], attrlen);
-
- if (attr_contentlen)
- *attr_contentlen = attrlen;
-
- cnt += attrlen + 3;
-
- match = true;
- break;
- } else {
- cnt += attrlen + 3; /* goto next */
- }
- }
-
- return match;
-}
-#endif /* CONFIG_8723AU_P2P */
-
-/* Baron adds to avoid FreeBSD warning */
-int ieee80211_is_empty_essid23a(const char *essid, int essid_len)
-{
- /* Single white space is for Linksys APs */
- if (essid_len == 1 && essid[0] == ' ')
- return 1;
-
- /* Otherwise, if the entire essid is 0, we assume it is hidden */
- while (essid_len) {
- essid_len--;
- if (essid[essid_len] != '\0')
- return 0;
- }
-
- return 1;
-}
-
static int rtw_get_cipher_info(struct wlan_network *pnetwork)
{
- u32 wpa_ielen;
- unsigned char *pbuf;
+ const u8 *pbuf;
int group_cipher = 0, pairwise_cipher = 0, is8021x = 0;
int ret = _FAIL;
- int r;
- pbuf = rtw_get_wpa_ie23a(&pnetwork->network.IEs[12], &wpa_ielen,
- pnetwork->network.IELength - 12);
+ int r, offset, plen;
+ char *pie;
+
+ offset = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
+ offsetof(struct ieee80211_mgmt, u);
+ pie = &pnetwork->network.IEs[offset];
+ plen = pnetwork->network.IELength - offset;
- if (pbuf && (wpa_ielen > 0)) {
+ 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", wpa_ielen));
- r = rtw_parse_wpa_ie23a(pbuf, wpa_ielen + 2, &group_cipher,
+ ("rtw_get_cipher_info: wpa_ielen: %d", 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;
ret = _SUCCESS;
}
} else {
- pbuf = rtw_get_wpa2_ie23a(&pnetwork->network.IEs[12], &wpa_ielen,
- pnetwork->network.IELength - 12);
+ pbuf = cfg80211_find_ie(WLAN_EID_RSN, pie, plen);
- if (pbuf && (wpa_ielen > 0)) {
+ if (pbuf && pbuf[1] > 0) {
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
("get RSN IE\n"));
- r = rtw_parse_wpa2_ie23a(pbuf, wpa_ielen + 2,
+ r = rtw_parse_wpa2_ie23a(pbuf, pbuf[1] + 2,
&group_cipher, &pairwise_cipher,
&is8021x);
if (r == _SUCCESS) {
unsigned int len;
unsigned char *p;
- memcpy(&cap, rtw_get_capability23a_from_ie(pnetwork->network.IEs), 2);
- cap = le16_to_cpu(cap);
+ cap = get_unaligned_le16(
+ rtw_get_capability23a_from_ie(pnetwork->network.IEs));
if (cap & WLAN_CAPABILITY_PRIVACY) {
bencrypt = 1;
pnetwork->network.Privacy = 1;
/* get bwmode and ch_offset */
/* parsing HT_CAP_IE */
p = rtw_get_ie23a(pnetwork->network.IEs + _FIXED_IE_LENGTH_,
- _HT_CAPABILITY_IE_, &len,
- pnetwork->network.IELength - _FIXED_IE_LENGTH_);
+ WLAN_EID_HT_CAPABILITY, &len,
+ pnetwork->network.IELength - _FIXED_IE_LENGTH_);
if (p && len > 0) {
pht_cap = (struct ieee80211_ht_cap *)(p + 2);
pnetwork->BcnInfo.ht_cap_info = pht_cap->cap_info;
}
/* parsing HT_INFO_IE */
p = rtw_get_ie23a(pnetwork->network.IEs + _FIXED_IE_LENGTH_,
- _HT_ADD_INFO_IE_, &len,
+ WLAN_EID_HT_OPERATION, &len,
pnetwork->network.IELength - _FIXED_IE_LENGTH_);
if (p && len > 0) {
pht_info = (struct HT_info_element *)(p + 2);
u8 _rtw_read823a(struct rtw_adapter *adapter, u32 addr)
{
u8 r_val;
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ struct _io_ops *io_ops = &adapter->io_ops;
- r_val = pintfhdl->io_ops._read8(pintfhdl, addr);
+ r_val = io_ops->_read8(adapter, addr);
return r_val;
}
u16 _rtw_read1623a(struct rtw_adapter *adapter, u32 addr)
{
u16 r_val;
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ struct _io_ops *io_ops = &adapter->io_ops;
- r_val = pintfhdl->io_ops._read16(pintfhdl, addr);
+ r_val = io_ops->_read16(adapter, addr);
return le16_to_cpu(r_val);
}
u32 _rtw_read3223a(struct rtw_adapter *adapter, u32 addr)
{
u32 r_val;
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ struct _io_ops *io_ops = &adapter->io_ops;
- r_val = pintfhdl->io_ops._read32(pintfhdl, addr);
+ r_val = io_ops->_read32(adapter, addr);
return le32_to_cpu(r_val);
}
int _rtw_write823a(struct rtw_adapter *adapter, u32 addr, u8 val)
{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ struct _io_ops *io_ops = &adapter->io_ops;
int ret;
- ret = pintfhdl->io_ops._write8(pintfhdl, addr, val);
+ ret = io_ops->_write8(adapter, addr, val);
return RTW_STATUS_CODE23a(ret);
}
int _rtw_write1623a(struct rtw_adapter *adapter, u32 addr, u16 val)
{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ struct _io_ops *io_ops = &adapter->io_ops;
int ret;
val = cpu_to_le16(val);
- ret = pintfhdl->io_ops._write16(pintfhdl, addr, val);
+ ret = io_ops->_write16(adapter, addr, val);
return RTW_STATUS_CODE23a(ret);
}
+
int _rtw_write3223a(struct rtw_adapter *adapter, u32 addr, u32 val)
{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ struct _io_ops *io_ops = &adapter->io_ops;
int ret;
val = cpu_to_le32(val);
- ret = pintfhdl->io_ops._write32(pintfhdl, addr, val);
+ ret = io_ops->_write32(adapter, addr, val);
return RTW_STATUS_CODE23a(ret);
}
int _rtw_writeN23a(struct rtw_adapter *adapter, u32 addr , u32 length , u8 *pdata)
{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = (struct intf_hdl*)&pio_priv->intf;
- int ret;
-
- ret = pintfhdl->io_ops._writeN(pintfhdl, addr, length, pdata);
-
- return RTW_STATUS_CODE23a(ret);
-}
-int _rtw_write823a_async23a(struct rtw_adapter *adapter, u32 addr, u8 val)
-{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ struct _io_ops *io_ops = &adapter->io_ops;
int ret;
- ret = pintfhdl->io_ops._write8_async(pintfhdl, addr, val);
+ ret = io_ops->_writeN(adapter, addr, length, pdata);
return RTW_STATUS_CODE23a(ret);
}
-int _rtw_write1623a_async(struct rtw_adapter *adapter, u32 addr, u16 val)
-{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
- int ret;
-
- val = cpu_to_le16(val);
- ret = pintfhdl->io_ops._write16_async(pintfhdl, addr, val);
-
- return RTW_STATUS_CODE23a(ret);
-}
-int _rtw_write3223a_async23a(struct rtw_adapter *adapter, u32 addr, u32 val)
-{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
- int ret;
-
- val = cpu_to_le32(val);
- ret = pintfhdl->io_ops._write32_async(pintfhdl, addr, val);
-
- return RTW_STATUS_CODE23a(ret);
-}
-
void _rtw_read_mem23a(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ struct _io_ops *io_ops = &adapter->io_ops;
if ((adapter->bDriverStopped == true) ||
(adapter->bSurpriseRemoved == true)) {
return;
}
- pintfhdl->io_ops._read_mem(pintfhdl, addr, cnt, pmem);
+ io_ops->_read_mem(adapter, addr, cnt, pmem);
}
void _rtw_write_mem23a(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ struct _io_ops *io_ops = &adapter->io_ops;
- pintfhdl->io_ops._write_mem(pintfhdl, addr, cnt, pmem);
+ io_ops->_write_mem(adapter, addr, cnt, pmem);
}
void _rtw_read_port23a(struct rtw_adapter *adapter, u32 addr, u32 cnt,
- struct recv_buf *rbuf)
+ struct recv_buf *rbuf)
{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ struct _io_ops *io_ops = &adapter->io_ops;
if ((adapter->bDriverStopped == true) ||
(adapter->bSurpriseRemoved == true)) {
return;
}
- pintfhdl->io_ops._read_port(pintfhdl, addr, cnt, rbuf);
+ io_ops->_read_port(adapter, addr, cnt, rbuf);
}
void _rtw_read_port23a_cancel(struct rtw_adapter *adapter)
{
- void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ void (*_read_port_cancel)(struct rtw_adapter *adapter);
+ struct _io_ops *io_ops = &adapter->io_ops;
- _read_port_cancel = pintfhdl->io_ops._read_port_cancel;
+ _read_port_cancel = io_ops->_read_port_cancel;
if (_read_port_cancel)
- _read_port_cancel(pintfhdl);
+ _read_port_cancel(adapter);
}
u32 _rtw_write_port23a(struct rtw_adapter *adapter, u32 addr, u32 cnt,
struct xmit_buf *xbuf)
{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ struct _io_ops *io_ops = &adapter->io_ops;
u32 ret = _SUCCESS;
- ret = pintfhdl->io_ops._write_port(pintfhdl, addr, cnt, xbuf);
-
- return ret;
-}
-
-u32 _rtw_write_port23a_and_wait23a(struct rtw_adapter *adapter, u32 addr, u32 cnt,
- struct xmit_buf *pxmitbuf, int timeout_ms)
-{
- int ret = _SUCCESS;
- struct submit_ctx sctx;
-
- rtw_sctx_init23a(&sctx, timeout_ms);
- pxmitbuf->sctx = &sctx;
-
- ret = _rtw_write_port23a(adapter, addr, cnt, pxmitbuf);
-
- if (ret == _SUCCESS)
- ret = rtw_sctx_wait23a(&sctx);
+ ret = io_ops->_write_port(adapter, addr, cnt, xbuf);
return ret;
}
void _rtw_write_port23a_cancel(struct rtw_adapter *adapter)
{
- void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &pio_priv->intf;
+ void (*_write_port_cancel)(struct rtw_adapter *adapter);
+ struct _io_ops *io_ops = &adapter->io_ops;
- _write_port_cancel = pintfhdl->io_ops._write_port_cancel;
+ _write_port_cancel = io_ops->_write_port_cancel;
if (_write_port_cancel)
- _write_port_cancel(pintfhdl);
-}
-
-int rtw_init_io_priv23a(struct rtw_adapter *padapter,
- void (*set_intf_ops)(struct _io_ops *pops))
-{
- struct io_priv *piopriv = &padapter->iopriv;
- struct intf_hdl *pintf = &piopriv->intf;
-
- if (set_intf_ops == NULL)
- return _FAIL;
-
- piopriv->padapter = padapter;
- pintf->padapter = padapter;
- pintf->pintf_dev = adapter_to_dvobj(padapter);
-
- set_intf_ops(&pintf->io_ops);
-
- return _SUCCESS;
+ _write_port_cancel(adapter);
}
/* we try to issue sitesurvey firstly */
if (pmlmepriv->LinkDetectInfo.bBusyTraffic == false ||
- rtw_to_roaming(padapter) > 0) {
+ padapter->mlmepriv.to_roaming > 0) {
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
("rtw_do_join23a(): site survey if scanned_queue "
"is empty\n."));
queue */
/* we try to issue sitesurvey firstly */
if (pmlmepriv->LinkDetectInfo.bBusyTraffic ==
- false || rtw_to_roaming(padapter) > 0) {
+ false || padapter->mlmepriv.to_roaming > 0){
/* DBG_8723A("rtw_do_join23a() when no "
"desired bss in scanning queue\n");
*/
}
u8 rtw_set_802_11_infrastructure_mode23a(struct rtw_adapter* padapter,
- enum ndis_802_11_net_infra networktype)
+ enum ndis_802_11_net_infra networktype)
{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_network *cur_network = &pmlmepriv->cur_network;
- enum ndis_802_11_net_infra* pold_state = &cur_network->network.InfrastructureMode;
-
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct wlan_network *cur_network = &pmlmepriv->cur_network;
+ enum ndis_802_11_net_infra* pold_state;
+ pold_state = &cur_network->network.InfrastructureMode;
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_,
- ("+rtw_set_802_11_infrastructure_mode23a: old =%d new =%d fw_state = 0x%08x\n",
+ ("+rtw_set_802_11_infrastructure_mode23a: old =%d new =%d "
+ "fw_state = 0x%08x\n",
*pold_state, networktype, get_fwstate(pmlmepriv)));
- if (*pold_state != networktype)
- {
+ if (*pold_state != networktype) {
spin_lock_bh(&pmlmepriv->lock);
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, (" change mode!"));
- /* DBG_8723A("change mode, old_mode =%d, new_mode =%d, fw_state = 0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */
+ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
+ (" change mode!"));
- if (*pold_state == Ndis802_11APMode)
- {
+ if (*pold_state == Ndis802_11APMode) {
/* change to other mode from Ndis802_11APMode */
cur_network->join_res = -1;
#endif
}
- if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||(*pold_state == Ndis802_11IBSS))
+ if (check_fwstate(pmlmepriv, _FW_LINKED) ||
+ *pold_state == Ndis802_11IBSS)
rtw_disassoc_cmd23a(padapter, 0, true);
- if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||
- (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true))
+ if (check_fwstate(pmlmepriv, _FW_LINKED) ||
+ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
rtw_free_assoc_resources23a(padapter, 1);
- if ((*pold_state == Ndis802_11Infrastructure) ||(*pold_state == Ndis802_11IBSS))
- {
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- rtw_indicate_disconnect23a(padapter); /* will clr Linked_state; before this function, we must have chked whether issue dis-assoc_cmd or not */
+ if (*pold_state == Ndis802_11Infrastructure ||
+ *pold_state == Ndis802_11IBSS) {
+ 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);
}
}
switch (networktype)
{
- case Ndis802_11IBSS:
- set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
- break;
+ case Ndis802_11IBSS:
+ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
+ break;
- case Ndis802_11Infrastructure:
- set_fwstate(pmlmepriv, WIFI_STATION_STATE);
- break;
+ case Ndis802_11Infrastructure:
+ set_fwstate(pmlmepriv, WIFI_STATION_STATE);
+ break;
- case Ndis802_11APMode:
- set_fwstate(pmlmepriv, WIFI_AP_STATE);
+ case Ndis802_11APMode:
+ set_fwstate(pmlmepriv, WIFI_AP_STATE);
#ifdef CONFIG_8723AU_AP_MODE
- start_ap_mode23a(padapter);
- /* rtw_indicate_connect23a(padapter); */
+ start_ap_mode23a(padapter);
+ /* rtw_indicate_connect23a(padapter); */
#endif
+ break;
- break;
-
- case Ndis802_11AutoUnknown:
- case Ndis802_11InfrastructureMax:
- break;
+ case Ndis802_11AutoUnknown:
+ case Ndis802_11InfrastructureMax:
+ break;
}
/* SecClearAllKeys(adapter); */
- /* RT_TRACE(COMP_OID_SET, DBG_LOUD, ("set_infrastructure: fw_state:%x after changing mode\n", */
- /* get_fwstate(pmlmepriv))); */
+ /* RT_TRACE(COMP_OID_SET, DBG_LOUD,
+ ("set_infrastructure: fw_state:%x after changing mode\n", */
+ /* get_fwstate(pmlmepriv))); */
spin_unlock_bh(&pmlmepriv->lock);
}
-
-
return true;
}
u16 rtw_get_cur_max_rate23a(struct rtw_adapter *adapter)
{
int i = 0;
- u8 *p;
+ const u8 *p;
u16 rate = 0, max_rate = 0;
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
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 (!check_fwstate(pmlmepriv, _FW_LINKED) &&
!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
return 0;
if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N|WIRELESS_11_5N)) {
- p = rtw_get_ie23a(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
- &ht_ielen, pcur_bss->IELength - 12);
- if (p && ht_ielen > 0) {
+ p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
+ &pcur_bss->IEs[12],
+ pcur_bss->IELength - 12);
+ if (p && p[1] > 0) {
pht_capie = (struct ieee80211_ht_cap *)(p + 2);
memcpy(&mcs_rate, &pht_capie->mcs, 2);
short_GI_20 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_20) ? 1:0;
short_GI_40 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_40) ? 1:0;
- rtw23a_hal_get_hwreg(adapter, HW_VAR_RF_TYPE,
- (u8 *)(&rf_type));
+ 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,
rtw_set_scan_deny_timer_hdl, (unsigned long)padapter);
}
-int _rtw_init_mlme_priv23a(struct rtw_adapter *padapter)
+int rtw_init_mlme_priv23a(struct rtw_adapter *padapter)
{
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
int res = _SUCCESS;
pmlmepriv->nic_hdl = padapter;
pmlmepriv->fw_state = 0;
- pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown;
- pmlmepriv->scan_mode=SCAN_ACTIVE;/* 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
+ pmlmepriv->cur_network.network.InfrastructureMode =
+ Ndis802_11AutoUnknown;
+ /* 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);
#ifdef CONFIG_8723AU_AP_MODE
static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
{
- if(*ppie)
- {
+ if (*ppie) {
kfree(*ppie);
*plen = 0;
- *ppie=NULL;
+ *ppie = NULL;
}
}
#endif
#ifdef CONFIG_8723AU_AP_MODE
kfree(pmlmepriv->assoc_req);
kfree(pmlmepriv->assoc_rsp);
- rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len);
- 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);
-
- rtw_free_mlme_ie_data(&pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->wfd_go_probe_resp_ie, &pmlmepriv->wfd_go_probe_resp_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
+ rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie,
+ &pmlmepriv->wps_beacon_ie_len);
+ 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);
+
+ rtw_free_mlme_ie_data(&pmlmepriv->wfd_beacon_ie,
+ &pmlmepriv->wfd_beacon_ie_len);
+ rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_req_ie,
+ &pmlmepriv->wfd_probe_req_ie_len);
+ rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_resp_ie,
+ &pmlmepriv->wfd_probe_resp_ie_len);
+ rtw_free_mlme_ie_data(&pmlmepriv->wfd_go_probe_resp_ie,
+ &pmlmepriv->wfd_go_probe_resp_ie_len);
+ rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_req_ie,
+ &pmlmepriv->wfd_assoc_req_ie_len);
#endif
}
-void _rtw_free_mlme_priv23a(struct mlme_priv *pmlmepriv)
+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)
return pnetwork;
}
-void _rtw_free_network23a(struct mlme_priv *pmlmepriv,
- struct wlan_network *pnetwork, u8 isfreeall)
+static void _rtw_free_network23a(struct mlme_priv *pmlmepriv,
+ struct wlan_network *pnetwork)
{
- u32 lifetime = SCANQUEUE_LIFETIME;
-
if (!pnetwork)
return;
if (pnetwork->fixed == true)
return;
- if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
- (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true))
- lifetime = 1;
-
- list_del_init(&pnetwork->list);
-
- kfree(pnetwork);
-}
-
-void _rtw_free_network23a_nolock23a(struct mlme_priv *pmlmepriv,
- struct wlan_network *pnetwork)
-{
-
- if (pnetwork == NULL)
- return;
-
- if (pnetwork->fixed == true)
- return;
-
list_del_init(&pnetwork->list);
kfree(pnetwork);
}
/*
- return the wlan_network with the matching addr
+ return the wlan_network with the matching addr
- Shall be calle under atomic context... to avoid possible racing condition...
+ Shall be calle under atomic context... to avoid possible racing condition...
*/
struct wlan_network *
-_rtw_find_network23a(struct rtw_queue *scanned_queue, u8 *addr)
+rtw_find_network23a(struct rtw_queue *scanned_queue, u8 *addr)
{
struct list_head *phead, *plist;
struct wlan_network *pnetwork = NULL;
plist = plist->next;
}
- if(plist == phead)
+ if (plist == phead)
pnetwork = NULL;
/* spin_unlock_bh(&scanned_queue->lock); */
return pnetwork;
}
-void _rtw_free_network23a_queue23a(struct rtw_adapter *padapter, u8 isfreeall)
+void rtw_free_network_queue23a(struct rtw_adapter *padapter)
{
struct list_head *phead, *plist, *ptmp;
struct wlan_network *pnetwork;
- struct mlme_priv* pmlmepriv = &padapter->mlmepriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct rtw_queue *scanned_queue = &pmlmepriv->scanned_queue;
spin_lock_bh(&scanned_queue->lock);
list_for_each_safe(plist, ptmp, phead) {
pnetwork = container_of(plist, struct wlan_network, list);
- _rtw_free_network23a(pmlmepriv,pnetwork, isfreeall);
+ _rtw_free_network23a(pmlmepriv, pnetwork);
}
spin_unlock_bh(&scanned_queue->lock);
-
}
-int rtw_if_up23a(struct rtw_adapter *padapter) {
-
+int rtw_if_up23a(struct rtw_adapter *padapter)
+{
int res;
- if(padapter->bDriverStopped || padapter->bSurpriseRemoved ||
- (check_fwstate(&padapter->mlmepriv, _FW_LINKED)== false)) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_if_up23a:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved));
- res=false;
- }
- else
- res= true;
+ if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
+ check_fwstate(&padapter->mlmepriv, _FW_LINKED) == false) {
+ RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
+ ("rtw_if_up23a:bDriverStopped(%d) OR "
+ "bSurpriseRemoved(%d)", padapter->bDriverStopped,
+ padapter->bSurpriseRemoved));
+ res = false;
+ } else
+ res = true;
return res;
}
pibss[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */
pibss[1] = 0x11;
pibss[2] = 0x87;
- pibss[3] = (u8)(curtime & 0xff) ;/* p[0]; */
- pibss[4] = (u8)((curtime>>8) & 0xff) ;/* p[1]; */
- pibss[5] = (u8)((curtime>>16) & 0xff) ;/* p[2]; */
+ pibss[3] = curtime & 0xff;/* p[0]; */
+ pibss[4] = (curtime >> 8) & 0xff;/* p[1]; */
+ pibss[5] = (curtime >> 16) & 0xff;/* p[2]; */
return;
}
-u8 *rtw_get_capability23a_from_ie(u8 *ie)
+void rtw_set_roaming(struct rtw_adapter *adapter, u8 to_roaming)
{
- return ie + 8 + 2;
+ if (to_roaming == 0)
+ adapter->mlmepriv.to_join = false;
+ adapter->mlmepriv.to_roaming = to_roaming;
}
-u16 rtw_get_capability23a(struct wlan_bssid_ex *bss)
+static void _rtw_roaming(struct rtw_adapter *padapter,
+ struct wlan_network *tgt_network)
{
- u16 val;
-
- memcpy((u8 *)&val, rtw_get_capability23a_from_ie(bss->IEs), 2);
-
- return le16_to_cpu(val);
-}
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct wlan_network *pnetwork;
+ int do_join_r;
-u8 *rtw_get_timestampe_from_ie23a(u8 *ie)
-{
- return ie + 0;
-}
+ if (tgt_network)
+ pnetwork = tgt_network;
+ else
+ pnetwork = &pmlmepriv->cur_network;
-u8 *rtw_get_beacon_interval23a_from_ie(u8 *ie)
-{
- return ie + 8;
-}
+ if (padapter->mlmepriv.to_roaming > 0) {
+ DBG_8723A("roaming from %s("MAC_FMT"), length:%d\n",
+ pnetwork->network.Ssid.ssid,
+ MAC_ARG(pnetwork->network.MacAddress),
+ pnetwork->network.Ssid.ssid_len);
+ memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid,
+ sizeof(struct cfg80211_ssid));
-int rtw_init_mlme_priv23a (struct rtw_adapter *padapter)/* struct mlme_priv *pmlmepriv) */
-{
- int res;
+ pmlmepriv->assoc_by_bssid = false;
- res = _rtw_init_mlme_priv23a(padapter);/* (pmlmepriv); */
+ while (1) {
+ do_join_r = rtw_do_join23a(padapter);
+ if (do_join_r == _SUCCESS)
+ break;
+ else {
+ DBG_8723A("roaming do_join return %d\n",
+ do_join_r);
+ pmlmepriv->to_roaming--;
- return res;
+ 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 rtw_free_mlme_priv23a (struct mlme_priv *pmlmepriv)
+void rtw23a_roaming(struct rtw_adapter *padapter,
+ struct wlan_network *tgt_network)
{
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("rtw_free_mlme_priv23a\n"));
- _rtw_free_mlme_priv23a(pmlmepriv);
-
+ spin_lock_bh(&pmlmepriv->lock);
+ _rtw_roaming(padapter, tgt_network);
+ spin_unlock_bh(&pmlmepriv->lock);
}
-void rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 is_freeall);
-void rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 is_freeall)/* struct wlan_network *pnetwork, _queue *free_queue) */
+__le16 *rtw_get_capability23a_from_ie(u8 *ie)
{
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- ("rtw_free_network ==> ssid = %s\n\n" ,
- pnetwork->network.Ssid.ssid));
- _rtw_free_network23a(pmlmepriv, pnetwork, is_freeall);
-
+ return (__le16 *)(ie + 8 + 2);
}
-void rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork);
-void rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork)
+u16 rtw_get_capability23a(struct wlan_bssid_ex *bss)
{
+ u16 val;
- /* RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("rtw_free_network ==> ssid = %s\n\n" , pnetwork->network.Ssid.ssid)); */
- _rtw_free_network23a_nolock23a(pmlmepriv, pnetwork);
+ memcpy(&val, rtw_get_capability23a_from_ie(bss->IEs), 2);
+ return le16_to_cpu(val);
}
-void rtw_free_network_queue23a(struct rtw_adapter* dev, u8 isfreeall)
+__le16 *rtw_get_beacon_interval23a_from_ie(u8 *ie)
{
-
- _rtw_free_network23a_queue23a(dev, isfreeall);
-
+ return (__le16 *)(ie + 8);
}
-/*
- return the wlan_network with the matching addr
-
- Shall be calle under atomic context... to avoid possible racing condition...
-*/
-struct wlan_network *
-rtw_find_network23a(struct rtw_queue *scanned_queue, u8 *addr)
+static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv,
+ struct wlan_network *pnetwork)
{
- struct wlan_network *pnetwork;
-
- pnetwork = _rtw_find_network23a(scanned_queue, addr);
-
- return pnetwork;
+ _rtw_free_network23a(pmlmepriv, pnetwork);
}
-int rtw_is_same_ibss23a(struct rtw_adapter *adapter, struct wlan_network *pnetwork)
+int rtw_is_same_ibss23a(struct rtw_adapter *adapter,
+ struct wlan_network *pnetwork)
{
int ret = true;
struct security_priv *psecuritypriv = &adapter->securitypriv;
- if ((psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_) &&
- (pnetwork->network.Privacy == 0))
- {
+ if (psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_ &&
+ pnetwork->network.Privacy == 0)
ret = false;
- }
- else if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) &&
- (pnetwork->network.Privacy == 1))
- {
+ else if (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_ &&
+ 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)
{
- /* RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("(%s,%d)(%s,%d)\n", */
- /* a->Ssid.Ssid, a->Ssid.SsidLength, b->Ssid.Ssid, b->Ssid.SsidLength)); */
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;
-
- memcpy((u8 *)&s_cap, rtw_get_capability23a_from_ie(src->IEs), 2);
- memcpy((u8 *)&d_cap, rtw_get_capability23a_from_ie(dst->IEs), 2);
+ u16 s_cap, d_cap;
- s_cap = le16_to_cpu(s_cap);
- d_cap = le16_to_cpu(d_cap);
+ s_cap = get_unaligned_le16(rtw_get_capability23a_from_ie(src->IEs));
+ d_cap = get_unaligned_le16(rtw_get_capability23a_from_ie(dst->IEs));
return ((src->Ssid.ssid_len == dst->Ssid.ssid_len) &&
/* (src->Configuration.DSConfig == dst->Configuration.DSConfig) && */
(d_cap & WLAN_CAPABILITY_ESS)));
}
-struct wlan_network *rtw_get_oldest_wlan_network23a(struct rtw_queue *scanned_queue)
+struct wlan_network *
+rtw_get_oldest_wlan_network23a(struct rtw_queue *scanned_queue)
{
struct list_head *plist, *phead;
-
struct wlan_network *pwlan;
struct wlan_network *oldest = NULL;
}
void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
- struct rtw_adapter * padapter, bool update_ie)
+ struct rtw_adapter *padapter, bool update_ie)
{
u8 ss_ori = dst->PhyInfo.SignalStrength;
u8 sq_ori = dst->PhyInfo.SignalQuality;
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",
+ 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->Configuration.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)) {
+ 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 */
+ /* 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 {
+ } else {
if (sq_smp != 101) { /* from the right channel */
- ss_final = ((u32)(src->PhyInfo.SignalStrength)+(u32)(dst->PhyInfo.SignalStrength)*4)/5;
- sq_final = ((u32)(src->PhyInfo.SignalQuality)+(u32)(dst->PhyInfo.SignalQuality)*4)/5;
- rssi_final = (src->Rssi+dst->Rssi*4)/5;
+ ss_final = ((u32)src->PhyInfo.SignalStrength +
+ (u32)dst->PhyInfo.SignalStrength * 4) / 5;
+ sq_final = ((u32)src->PhyInfo.SignalQuality +
+ (u32)dst->PhyInfo.SignalQuality * 4) / 5;
+ rssi_final = src->Rssi+dst->Rssi * 4 / 5;
} else {
- /* bss info not receving from the right channel, use the original RX signal infos */
+ /* bss info not receving from the right channel, use
+ the original RX signal infos */
ss_final = dst->PhyInfo.SignalStrength;
sq_final = dst->PhyInfo.SignalQuality;
rssi_final = dst->Rssi;
}
if (update_ie)
- memcpy((u8 *)dst, (u8 *)src, get_wlan_bssid_ex_sz(src));
+ memcpy(dst, src, get_wlan_bssid_ex_sz(src));
dst->PhyInfo.SignalStrength = ss_final;
dst->PhyInfo.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,
+ DBG_8723A("%s %s(%pM), SignalStrength:%u, SignalQuality:%u, "
+ "RawRSSI:%ld\n", __func__, dst->Ssid.ssid, dst->MacAddress,
dst->PhyInfo.SignalStrength,
dst->PhyInfo.SignalQuality, dst->Rssi);
-
}
-static void update_current_network(struct rtw_adapter *adapter, struct wlan_bssid_ex *pnetwork)
+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)== true) && (is_same_network23a(&pmlmepriv->cur_network.network, pnetwork)))
- {
- /* RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"Same Network\n"); */
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- /* if(pmlmepriv->cur_network.network.IELength<= pnetwork->IELength) */
- {
- update_network23a(&pmlmepriv->cur_network.network, pnetwork,adapter, true);
- rtw_update_protection23a(adapter, (pmlmepriv->cur_network.network.IEs) + sizeof (struct ndis_802_11_fixed_ies),
- pmlmepriv->cur_network.network.IELength);
- }
+ 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 +
+ sizeof (struct ndis_802_11_fixed_ies),
+ pmlmepriv->cur_network.network.IELength);
}
-
}
/*
Caller must hold pmlmepriv->lock first.
*/
-void rtw_update_scanned_network23a(struct rtw_adapter *adapter, struct wlan_bssid_ex *target)
+void rtw_update_scanned_network23a(struct rtw_adapter *adapter,
+ struct wlan_bssid_ex *target)
{
struct list_head *plist, *phead;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
/* target.reserved == 1, means that scanned network is
* a bcn frame. */
- if ((pnetwork->network.IELength>target->IELength) &&
- (target->reserved == 1))
+ if (pnetwork->network.IELength > target->IELength &&
+ target->reserved == 1)
update_ie = false;
- update_network23a(&pnetwork->network, target,adapter, update_ie);
+ update_network23a(&pnetwork->network, target,adapter,
+ update_ie);
}
exit:
spin_unlock_bh(&queue->lock);
-
}
-void rtw_add_network(struct rtw_adapter *adapter, struct wlan_bssid_ex *pnetwork)
+static void rtw_add_network(struct rtw_adapter *adapter,
+ struct wlan_bssid_ex *pnetwork)
{
update_current_network(adapter, pnetwork);
rtw_update_scanned_network23a(adapter, pnetwork);
/* (3) WMM */
/* (4) HT */
/* (5) others */
-int rtw_is_desired_network(struct rtw_adapter *adapter, struct wlan_network *pnetwork)
+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;
desired_encmode = psecuritypriv->ndisencryptstatus;
privacy = pnetwork->network.Privacy;
- if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
- {
- if (rtw_get_wps_ie23a(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen)!= NULL)
- {
+ if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
+ if (rtw_get_wps_ie23a(pnetwork->network.IEs + _FIXED_IE_LENGTH_,
+ pnetwork->network.IELength -
+ _FIXED_IE_LENGTH_, NULL, &wps_ielen))
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))
+ 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);
+ 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) == true)
- {
- if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
+ if (pnetwork->network.InfrastructureMode !=
+ pmlmepriv->cur_network.network.InfrastructureMode)
bselected = false;
}
}
/* TODO: Perry : For Power Management */
-void rtw_atimdone_event_callback23a(struct rtw_adapter *adapter , u8 *pbuf)
+void rtw_atimdone_event_callback23a(struct rtw_adapter *adapter, u8 *pbuf)
{
-
RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("receive atimdone_evet\n"));
return;
}
-void rtw_survey_event_cb23a(struct rtw_adapter *adapter, u8 *pbuf)
+void rtw_survey_event_cb23a(struct rtw_adapter *adapter, u8 *pbuf)
{
u32 len;
struct wlan_bssid_ex *pnetwork;
pnetwork = (struct wlan_bssid_ex *)pbuf;
- RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_survey_event_cb23a, ssid=%s\n", pnetwork->Ssid.ssid));
+ 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_,("\n ****rtw_survey_event_cb23a: return a wrong bss ***\n"));
+ if (len > (sizeof(struct wlan_bssid_ex))) {
+ RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,
+ ("\n ****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)) == true)
- {
- /* RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,"rtw_survey_event_cb23a : WIFI_ADHOC_MASTER_STATE\n\n"); */
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
+ /* RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
+ "rtw_survey_event_cb23a : WIFI_ADHOC_MASTER_STATE\n\n"); */
if (ether_addr_equal(pmlmepriv->cur_network.network.MacAddress,
pnetwork->MacAddress)) {
- struct wlan_network* ibss_wlan = NULL;
+ struct wlan_network* ibss_wlan;
- memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8);
+ memcpy(pmlmepriv->cur_network.network.IEs,
+ pnetwork->IEs, 8);
spin_lock_bh(&pmlmepriv->scanned_queue.lock);
- ibss_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, pnetwork->MacAddress);
- if (ibss_wlan)
- {
- memcpy(ibss_wlan->network.IEs , pnetwork->IEs, 8);
+ ibss_wlan = rtw_find_network23a(
+ &pmlmepriv->scanned_queue,
+ pnetwork->MacAddress);
+ if (ibss_wlan) {
+ memcpy(ibss_wlan->network.IEs,
+ pnetwork->IEs, 8);
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
goto exit;
}
}
/* lock pmlmepriv->lock when you accessing network_q */
- if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == false)
- {
+ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == false) {
if (pnetwork->Ssid.ssid[0] == 0)
pnetwork->Ssid.ssid_len = 0;
return;
}
-void rtw_surveydone_event_callback23a(struct rtw_adapter *adapter, u8 *pbuf)
+void rtw_surveydone_event_callback23a(struct rtw_adapter *adapter, u8 *pbuf)
{
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
+ struct wlan_bssid_ex *pdev_network;
+ u8 *pibss;
spin_lock_bh(&pmlmepriv->lock);
pmlmepriv->wps_probe_req_ie = NULL;
}
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_surveydone_event_callback23a: fw_state:%x\n\n", get_fwstate(pmlmepriv)));
+ RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
+ ("rtw_surveydone_event_callback23a: fw_state:%x\n\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)));
+ 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) {
- if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
- if (rtw_select_and_join_from_scanned_queue23a(pmlmepriv) == _SUCCESS) {
+ if (rtw_select_and_join_from_scanned_queue23a(
+ pmlmepriv) == _SUCCESS) {
mod_timer(&pmlmepriv->assoc_timer,
jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
} else {
- struct wlan_bssid_ex *pdev_network = &adapter->registrypriv.dev_network;
- u8 *pibss = adapter->registrypriv.dev_network.MacAddress;
+ pdev_network = &adapter->registrypriv.dev_network;
+ pibss = adapter->registrypriv.dev_network.MacAddress;
- _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
+ _clr_fwstate_(pmlmepriv,
+ _FW_UNDER_SURVEY);
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("switching to adhoc master\n"));
+ RT_TRACE(_module_rtl871x_mlme_c_,
+ _drv_err_,
+ ("switching to adhoc "
+ "master\n"));
- memset(&pdev_network->Ssid, 0, sizeof(struct cfg80211_ssid));
- memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct cfg80211_ssid));
+ memset(&pdev_network->Ssid, 0,
+ sizeof(struct cfg80211_ssid));
+ memcpy(&pdev_network->Ssid,
+ &pmlmepriv->assoc_ssid,
+ sizeof(struct cfg80211_ssid));
- rtw_update_registrypriv_dev_network23a(adapter);
+ rtw_update_registrypriv_dev_network23a(
+ adapter);
rtw_generate_random_ibss23a(pibss);
- pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
+ pmlmepriv->fw_state =
+ WIFI_ADHOC_MASTER_STATE;
- if (rtw_createbss_cmd23a(adapter)!= _SUCCESS)
- {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Error =>rtw_createbss_cmd23a status FAIL\n"));
- }
+ if (rtw_createbss_cmd23a(adapter) !=
+ _SUCCESS)
+ RT_TRACE(_module_rtl871x_mlme_c_,
+ _drv_err_,
+ ("Error =>rtw_createbss_cmd23a"
+ " status FAIL\n"));
pmlmepriv->to_join = false;
}
int ret;
set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
pmlmepriv->to_join = false;
- ret = rtw_select_and_join_from_scanned_queue23a(pmlmepriv);
+ ret = rtw_select_and_join_from_scanned_queue23a(
+ pmlmepriv);
if (ret == _SUCCESS) {
unsigned long e;
e = msecs_to_jiffies(MAX_JOIN_TIMEOUT);
mod_timer(&pmlmepriv->assoc_timer, jiffies + e);
- } else if (ret == 2)/* there is no need to wait for join */
- {
+ } else if (ret == 2) {/* there is no need to wait */
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
rtw_indicate_connect23a(adapter);
} else {
- DBG_8723A("try_to_join, but select scanning queue fail, to_roaming:%d\n", rtw_to_roaming(adapter));
- if (rtw_to_roaming(adapter) != 0) {
- if (--pmlmepriv->to_roaming == 0
- || _SUCCESS != rtw_sitesurvey_cmd23a(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)
- ) {
+ 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 {
+ 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);
-#ifdef CONFIG_8723AU_P2P
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- p2p_ps_wk_cmd23a(adapter, P2P_PS_SCAN_DONE, 0);
-#endif /* CONFIG_8723AU_P2P */
-
rtw_os_xmit_schedule23a(adapter);
- if(pmlmeext->sitesurvey_res.bss_cnt == 0)
+ if (pmlmeext->sitesurvey_res.bss_cnt == 0)
rtw_hal_sreset_reset23a(adapter);
rtw_cfg80211_surveydone_event_callback(adapter);
-
}
void rtw_dummy_event_callback23a(struct rtw_adapter *adapter , u8 *pbuf)
{
}
-static void free_scanqueue(struct mlme_priv *pmlmepriv)
+static void free_scanqueue(struct mlme_priv *pmlmepriv)
{
struct wlan_network *pnetwork;
struct rtw_queue *scan_queue = &pmlmepriv->scanned_queue;
}
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)
+ *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 = NULL;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct sta_priv *pstapriv = &adapter->stapriv;
+ 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="MAC_FMT" ssid=%s\n",
- MAC_ARG(tgt_network->network.MacAddress), tgt_network->network.Ssid.ssid));
-
- if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE))
- {
- struct sta_info* psta;
-
- psta = rtw_get_stainfo23a(&adapter->stapriv, tgt_network->network.MacAddress);
+ 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="MAC_FMT" ssid=%s\n",
+ MAC_ARG(tgt_network->network.MacAddress),
+ tgt_network->network.Ssid.ssid));
- {
- spin_lock_bh(&pstapriv->sta_hash_lock);
- rtw_free_stainfo23a(adapter, psta);
- }
+ 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))
- {
- struct sta_info* psta;
-
+ 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);
rtw_init_bcmc_stainfo23a(adapter);
}
- if(lock_scanned_queue)
+ 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 = 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\n"));
+ 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))
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) &&
+ adapter->stapriv.asoc_sta_count == 1)
rtw_free_network_nolock(pmlmepriv, pwlan);
- if(lock_scanned_queue)
+ if (lock_scanned_queue)
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
pmlmepriv->key_mask = 0;
-
}
/*
*/
void rtw_indicate_connect23a(struct rtw_adapter *padapter)
{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_connect23a\n"));
+ RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
+ ("+rtw_indicate_connect23a\n"));
pmlmepriv->to_join = false;
- if(!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
+ if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
set_fwstate(pmlmepriv, _FW_LINKED);
rtw_led_control(padapter, LED_CTL_LINK);
- rtw_os_indicate_connect23a(padapter);
+ 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)));
-
+ 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
-*/
+ *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"));
+ 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 (rtw_to_roaming(padapter) > 0)
+ if (padapter->mlmepriv.to_roaming > 0)
_clr_fwstate_(pmlmepriv, _FW_LINKED);
if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) ||
- (rtw_to_roaming(padapter) <= 0)) {
+ padapter->mlmepriv.to_roaming <= 0) {
rtw_os_indicate_disconnect23a(padapter);
/* set ips_deny_time to avoid enter IPS before LPS leave */
}
-#ifdef CONFIG_8723AU_P2P
- p2p_ps_wk_cmd23a(padapter, P2P_PS_DISABLE, 1);
-#endif /* CONFIG_8723AU_P2P */
-
rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_DISCONNECT, 1);
-
-}
-
-inline void rtw_indicate_scan_done23a(struct rtw_adapter *padapter, bool aborted)
-{
- rtw_os_indicate_scan_done23a(padapter, aborted);
}
void rtw_scan_abort23a(struct rtw_adapter *adapter)
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(FUNC_NDEV_FMT"fw_state = _FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev));
+ DBG_8723A(FUNC_NDEV_FMT "fw_state = _FW_UNDER_SURVEY!\n",
+ FUNC_NDEV_ARG(adapter->pnetdev));
msleep(20);
}
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved)
- DBG_8723A(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev));
- rtw_indicate_scan_done23a(adapter, true);
+ DBG_8723A(FUNC_NDEV_FMT "waiting for scan_abort time "
+ "out!\n", FUNC_NDEV_ARG(adapter->pnetdev));
+ 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)
+static struct sta_info *
+rtw_joinbss_update_stainfo(struct rtw_adapter *padapter,
+ struct wlan_network *pnetwork)
{
int i;
- struct sta_info *bmc_sta, *psta = NULL;
+ 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 == NULL) {
- psta = rtw_alloc_stainfo23a(pstapriv, pnetwork->network.MacAddress);
- }
+ if (!psta)
+ psta = rtw_alloc_stainfo23a(pstapriv,
+ pnetwork->network.MacAddress);
- if (psta) /* update ptarget_sta */
- {
+ if (psta) { /* update ptarget_sta */
DBG_8723A("%s\n", __func__);
psta->aid = pnetwork->join_res;
rtw_hal_set_odm_var23a(padapter, HAL_ODM_STA_INFO, psta, true);
/* security related */
- if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
- {
+ if (padapter->securitypriv.dot11AuthAlgrthm ==
+ dot11AuthAlgrthm_8021X) {
padapter->securitypriv.binstallGrpkey = false;
padapter->securitypriv.busetkipkey = false;
padapter->securitypriv.bgrpkey_handshake = false;
psta->ieee8021x_blocked = true;
- psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
+ psta->dot118021XPrivacy =
+ padapter->securitypriv.dot11PrivacyAlgrthm;
- memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof (union Keytype));
+ memset(&psta->dot118021x_UncstKey, 0,
+ sizeof (union Keytype));
- memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof (union Keytype));
- memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof (union Keytype));
+ memset(&psta->dot11tkiprxmickey, 0,
+ sizeof (union Keytype));
+ memset(&psta->dot11tkiptxmickey, 0,
+ sizeof (union Keytype));
- memset((u8 *)&psta->dot11txpn, 0, sizeof (union pn48));
- memset((u8 *)&psta->dot11rxpn, 0, sizeof (union pn48));
+ 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 tramsmitted. */
- if (padapter->securitypriv.wps_ie_len != 0)
- {
+ /* And the Wi-Fi driver shouldn't allow the data packet
+ to be tramsmitted. */
+ 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, reseting rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
+ /* for A-MPDU Rx reordering buffer control for bmc_sta &
+ * sta_info */
+ /* if A-MPDU Rx is enabled, reseting
+ 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++)
- {
+ 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;
- preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
+ /* 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 = &precvpriv->recvreorder_ctrl[i]; */
+ 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;
- preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
+ /* max_ampdu_sz; ex. 32(kbytes) ->
+ wsize_b = 32 */
+ preorder_ctrl->wsize_b = 64;
}
}
/* 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)
+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_, ("\nfw_state:%x, BSSID:"MAC_FMT"\n"
- , get_fwstate(pmlmepriv), MAC_ARG(pnetwork->network.MacAddress)));
+ RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
+ ("\nfw_state:%x, BSSID:"MAC_FMT"\n", get_fwstate(pmlmepriv),
+ MAC_ARG(pnetwork->network.MacAddress)));
/* why not use ptarget_wlan?? */
- memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length);
+ 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);
+ memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0],
+ MAX_IE_SZ);
cur_network->aid = pnetwork->join_res;
rtw_set_signal_stat_timer(&padapter->recvpriv);
- padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength;
- padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality;
- /* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */
- padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength);
+ padapter->recvpriv.signal_strength =
+ ptarget_wlan->network.PhyInfo.SignalStrength;
+ padapter->recvpriv.signal_qual =
+ ptarget_wlan->network.PhyInfo.SignalQuality;
+ /*
+ * the ptarget_wlan->network.Rssi is raw data, we use
+ * ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled)
+ */
+ padapter->recvpriv.rssi = translate_percentage_to_dbm(
+ ptarget_wlan->network.PhyInfo.SignalStrength);
DBG_8723A("%s signal_strength:%3u, rssi:%3d, signal_qual:%3u\n",
__func__, padapter->recvpriv.signal_strength,
padapter->recvpriv.rssi, padapter->recvpriv.signal_qual);
break;
default:
pmlmepriv->fw_state = WIFI_NULL_STATE;
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Invalid network_mode\n"));
+ RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
+ ("Invalid network_mode\n"));
break;
}
- rtw_update_protection23a(padapter, (cur_network->network.IEs) + sizeof (struct ndis_802_11_fixed_ies),
- (cur_network->network.IELength));
+ rtw_update_protection23a(padapter, cur_network->network.IEs +
+ sizeof (struct ndis_802_11_fixed_ies),
+ cur_network->network.IELength);
- rtw_update_ht_cap23a(padapter, cur_network->network.IEs, cur_network->network.IELength);
+ rtw_update_ht_cap23a(padapter, cur_network->network.IEs,
+ cur_network->network.IELength);
}
-/* Notes: the fucntion 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). */
+/*
+ * Notes:
+ * the fucntion 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)
{
- static u8 retry=0;
- struct sta_info *ptarget_sta= NULL, *pcur_sta = NULL;
- struct sta_priv *pstapriv = &adapter->stapriv;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct wlan_network *pnetwork = (struct wlan_network *)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 = NULL, *ptarget_wlan = NULL;
- unsigned int the_same_macaddr = false;
+ 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));
+ RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,
+ ("joinbss event call back received with res=%d\n",
+ pnetwork->join_res));
rtw_get_encrypt_decrypt_from_registrypriv23a(adapter);
if (pmlmepriv->assoc_ssid.ssid_len == 0) {
- RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("@@@@@ joinbss event call back for Any SSid\n"));
+ 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",
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_,("\n\n ***joinbss_evt_callback return a wrong bss ***\n\n"));
+ if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) {
+ RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,
+ ("\n\n ***joinbss_evt_callback return a wrong bss "
+ "***\n\n"));
return;
}
spin_lock_bh(&pmlmepriv->lock);
- RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n rtw23a_joinbss_event_cb !! _enter_critical\n"));
+ RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,
+ ("\n rtw23a_joinbss_event_cb !! _enter_critical\n"));
- if(pnetwork->join_res > 0)
- {
+ if (pnetwork->join_res > 0) {
spin_lock_bh(&pmlmepriv->scanned_queue.lock);
- retry = 0;
- if (check_fwstate(pmlmepriv,_FW_UNDER_LINKING))
- {
+ if (check_fwstate(pmlmepriv,_FW_UNDER_LINKING)) {
/* s1. find ptarget_wlan */
- if(check_fwstate(pmlmepriv, _FW_LINKED))
- {
- if(the_same_macaddr == true)
- {
+ if (check_fwstate(pmlmepriv, _FW_LINKED)) {
+ if (the_same_macaddr == true) {
ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
- }
- else
- {
+ } else {
pcur_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
- if(pcur_wlan) pcur_wlan->fixed = false;
+ if (pcur_wlan)
+ pcur_wlan->fixed = false;
pcur_sta = rtw_get_stainfo23a(pstapriv, cur_network->network.MacAddress);
- if(pcur_sta) {
+ if (pcur_sta) {
spin_lock_bh(&pstapriv->sta_hash_lock);
- rtw_free_stainfo23a(adapter, pcur_sta);
+ 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) == true) {
- if(ptarget_wlan) ptarget_wlan->fixed = true;
+ 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) == true) {
- 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"));
+ 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) == true)
- {
- ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork);
- if(ptarget_sta==NULL)
- {
- RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Can't update stainfo when joinbss_event callback\n"));
+ /* 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) == true)
- {
+ 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", get_fwstate(pmlmepriv)));
+ 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",
+ 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"));
+ 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",
goto ignore_joinbss_callback;
}
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
- } else if(pnetwork->join_res == -4) {
+ } 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))) {
+ 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)));
+ ("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,
void rtw23a_joinbss_event_cb(struct rtw_adapter *adapter, u8 *pbuf)
{
- struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
+ struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
mlmeext_joinbss_event_callback23a(adapter, pnetwork->join_res);
rtw_os_xmit_schedule23a(adapter);
-
-}
-
-/* FOR AP , AD-HOC mode */
-void rtw_stassoc_hw_rpt23a(struct rtw_adapter *adapter, struct sta_info *psta)
-{
- u16 media_status;
-
- if (psta == NULL) return;
-
- media_status = (psta->mac_id<<8)|1; /* MACID|OPMODE:1 connect */
- rtw_hal_set_hwreg23a(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
}
void rtw_stassoc_event_callback23a(struct rtw_adapter *adapter, u8 *pbuf)
{
struct sta_info *psta;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct stassoc_event *pstassoc = (struct stassoc_event*)pbuf;
+ struct stassoc_event *pstassoc = (struct stassoc_event*)pbuf;
struct wlan_network *cur_network = &pmlmepriv->cur_network;
- struct wlan_network *ptarget_wlan = NULL;
+ struct wlan_network *ptarget_wlan;
- if(rtw_access_ctrl23a(adapter, pstassoc->macaddr) == false)
+ if (rtw_access_ctrl23a(adapter, pstassoc->macaddr) == false)
return;
#ifdef CONFIG_8723AU_AP_MODE
- if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
- {
+ 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);
-
- rtw_stassoc_hw_rpt23a(adapter,psta);
}
return;
}
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"));
- return; /* between drv has received this event before and fw have not yet to set key to CAM_ENTRY) */
+ 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);
- if (psta == NULL) {
- RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Can't alloc sta_info when rtw_stassoc_event_callback23a\n"));
+ if (!psta) {
+ RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,
+ ("Can't alloc sta_info when "
+ "rtw_stassoc_event_callback23a\n"));
return;
}
/* psta->aid = (uint)pstassoc->cam_id; */
DBG_8723A("%s\n",__func__);
/* for ad-hoc mode */
- rtw_hal_set_odm_var23a(adapter,HAL_ODM_STA_INFO,psta,true);
-
- rtw_stassoc_hw_rpt23a(adapter,psta);
+ rtw_hal_set_odm_var23a(adapter, HAL_ODM_STA_INFO, psta, true);
- if(adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)
- psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm;
+ 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)==true ) ||
- (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==true ) )
- {
- if(adapter->stapriv.asoc_sta_count== 2)
- {
+ 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;
+ 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);
void rtw_stadel_event_callback23a(struct rtw_adapter *adapter, u8 *pbuf)
{
- int mac_id=-1;
+ int mac_id;
struct sta_info *psta;
- struct wlan_network* pwlan = NULL;
- struct wlan_bssid_ex *pdev_network=NULL;
- u8* pibss = NULL;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct stadel_event *pstadel = (struct stadel_event*)pbuf;
- struct sta_priv *pstapriv = &adapter->stapriv;
+ struct wlan_network* pwlan;
+ struct wlan_bssid_ex *pdev_network;
+ u8 *pibss;
+ 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)
+ if (psta)
mac_id = psta->mac_id;
else
mac_id = pstadel->mac_id;
- DBG_8723A("%s(mac_id=%d)=" MAC_FMT "\n", __func__, mac_id, MAC_ARG(pstadel->macaddr));
-
- if(mac_id>=0) {
- u16 media_status;
- media_status = (mac_id<<8)|0; /* MACID|OPMODE:0 means disconnect */
- /* for STA,AP,ADHOC mode, report disconnect stauts to FW */
- rtw_hal_set_hwreg23a(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
- }
+ DBG_8723A("%s(mac_id=%d)=" MAC_FMT "\n", __func__, mac_id,
+ MAC_ARG(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 (rtw_to_roaming(adapter) > 0)
- pmlmepriv->to_roaming--; /* this stadel_event is caused by roaming, decrease to_roaming */
- else if (rtw_to_roaming(adapter) == 0)
+ 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 (*((unsigned short *)(pstadel->rsvd)) != WLAN_REASON_EXPIRATION_CHK)
+ if (*((u16 *)pstadel->rsvd) != WLAN_REASON_EXPIRATION_CHK)
rtw_set_roaming(adapter, 0); /* don't roam */
rtw_free_uc_swdec_pending_queue23a(adapter);
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);
+ 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);
- _rtw23a_roaming(adapter, tgt_network);
+ _rtw_roaming(adapter, tgt_network);
}
if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_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);
- if (adapter->stapriv.asoc_sta_count == 1) /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
- {
+ /* 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 = 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);
}
pdev_network = &adapter->registrypriv.dev_network;
pibss = adapter->registrypriv.dev_network.MacAddress;
- memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network));
+ memcpy(pdev_network, &tgt_network->network,
+ get_wlan_bssid_ex_sz(&tgt_network->network));
memset(&pdev_network->Ssid, 0,
sizeof(struct cfg80211_ssid));
rtw_generate_random_ibss23a(pibss);
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
- {
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
_clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
}
- if (rtw_createbss_cmd23a(adapter)!= _SUCCESS)
- {
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("***Error =>stadel_event_callback: rtw_createbss_cmd23a status FAIL***\n "));
-
+ if (rtw_createbss_cmd23a(adapter) != _SUCCESS) {
+ RT_TRACE(_module_rtl871x_ioctl_set_c_,
+ _drv_err_,
+ ("***Error =>stadel_event_callback: "
+ "rtw_createbss_cmd23a status "
+ "FAIL***\n"));
}
-
}
-
}
spin_unlock_bh(&pmlmepriv->lock);
-
}
void rtw_cpwm_event_callback23a(struct rtw_adapter *padapter, u8 *pbuf)
{
-
- RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("+rtw_cpwm_event_callback23a !!!\n"));
-
+ RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
+ ("+rtw_cpwm_event_callback23a !!!\n"));
}
/*
DBG_8723A("%s, fw_state=%x\n", __func__, get_fwstate(pmlmepriv));
- if(adapter->bDriverStopped ||adapter->bSurpriseRemoved)
+ if (adapter->bDriverStopped ||adapter->bSurpriseRemoved)
return;
spin_lock_bh(&pmlmepriv->lock);
- if (rtw_to_roaming(adapter) > 0) { /* join timeout caused by roaming */
- while(1) {
+ if (adapter->mlmepriv.to_roaming > 0) {
+ /* join timeout caused by roaming */
+ while (1) {
pmlmepriv->to_roaming--;
- if (rtw_to_roaming(adapter) != 0) { /* try another */
+ if (adapter->mlmepriv.to_roaming != 0) {
+ /* try another */
DBG_8723A("%s try another roaming\n", __func__);
- if (_SUCCESS!= (do_join_r = rtw_do_join23a(adapter))) {
- DBG_8723A("%s roaming do_join return %d\n", __func__ , do_join_r);
+ do_join_r = rtw_do_join23a(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__);
+ DBG_8723A("%s We've try roaming but fail\n",
+ __func__);
rtw_indicate_disconnect23a(adapter);
break;
}
rtw_indicate_disconnect23a(adapter);
free_scanqueue(pmlmepriv);/* */
- /* indicate disconnect for the case that join_timeout and check_fwstate != FW_LINKED */
+ /* indicate disconnect for the case that join_timeout and
+ check_fwstate != FW_LINKED */
rtw_cfg80211_indicate_disconnect(adapter);
}
struct rtw_adapter *adapter = (struct rtw_adapter *)data;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- DBG_8723A(FUNC_ADPT_FMT" fw_state =%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
+ DBG_8723A(FUNC_ADPT_FMT" fw_state =%x\n", FUNC_ADPT_ARG(adapter),
+ get_fwstate(pmlmepriv));
spin_lock_bh(&pmlmepriv->lock);
spin_unlock_bh(&pmlmepriv->lock);
- rtw_indicate_scan_done23a(adapter, true);
+ rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter->rtw_wdev), true);
}
static void rtw_auto_scan_handler(struct rtw_adapter *padapter)
if (pmlmepriv->scan_interval == 0) {
DBG_8723A("%s\n", __func__);
rtw_set_802_11_bssid23a_list_scan(padapter, NULL, 0);
- pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */
+ /* 30*2 sec = 60sec */
+ pmlmepriv->scan_interval = SCAN_INTERVAL;
}
}
}
if (adapter->hw_init_completed == false)
goto out;
- if ((adapter->bDriverStopped == true)||(adapter->bSurpriseRemoved == true))
+ if (adapter->bDriverStopped == true ||
+ adapter->bSurpriseRemoved == true)
goto out;
if (adapter->net_closed == true)
rtw_dynamic_chk_wk_cmd23a(adapter);
- if (pregistrypriv->wifi_spec == 1)
- {
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-#endif
- {
- /* auto site survey */
- rtw_auto_scan_handler(adapter);
- }
+ if (pregistrypriv->wifi_spec == 1) {
+ /* auto site survey */
+ rtw_auto_scan_handler(adapter);
}
out:
mod_timer(&adapter->mlmepriv.dynamic_chk_timer,
{
struct mlme_priv *mlmepriv = &adapter->mlmepriv;
atomic_set(&mlmepriv->set_scan_deny, 0);
- if (0)
- DBG_8723A(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
}
void rtw_set_scan_deny_timer_hdl(unsigned long data)
{
struct mlme_priv *mlmepriv = &adapter->mlmepriv;
- if (0)
- DBG_8723A(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
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)
#endif
/*
-* Select a new join candidate from the original @param candidate and @param competitor
+* 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)
+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 = container_of(pmlmepriv, struct rtw_adapter, mlmepriv);
+ struct rtw_adapter *adapter;
+
+ adapter = container_of(pmlmepriv, struct rtw_adapter, mlmepriv);
/* check bssid, if needed */
if (pmlmepriv->assoc_by_bssid == true) {
goto exit;
}
- if (rtw_is_desired_network(adapter, competitor) == false)
+ if (rtw_is_desired_network(adapter, competitor) == false)
goto exit;
- if (rtw_to_roaming(adapter) > 0) {
+ if (adapter->mlmepriv.to_roaming > 0) {
unsigned int passed;
passed = jiffies_to_msecs(jiffies - competitor->last_scanned);
goto exit;
}
- if (*candidate == NULL ||(*candidate)->network.Rssi<competitor->network.Rssi) {
+ 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("MAC_FMT") rssi:%d\n",
- pmlmepriv->assoc_by_bssid,
- pmlmepriv->assoc_ssid.ssid,
- rtw_to_roaming(adapter),
- (*candidate)->network.Ssid.ssid,
- MAC_ARG((*candidate)->network.MacAddress),
- (int)(*candidate)->network.Rssi);
+ DBG_8723A("[by_bssid:%u][assoc_ssid:%s][to_roaming:%u] "
+ "new candidate: %s("MAC_FMT") rssi:%d\n",
+ pmlmepriv->assoc_by_bssid,
+ pmlmepriv->assoc_ssid.ssid,
+ adapter->mlmepriv.to_roaming,
+ (*candidate)->network.Ssid.ssid,
+ MAC_ARG((*candidate)->network.MacAddress),
+ (int)(*candidate)->network.Rssi);
}
exit:
struct list_head *phead, *plist, *ptmp;
struct rtw_adapter *adapter;
struct rtw_queue *queue = &pmlmepriv->scanned_queue;
- struct wlan_network *pnetwork = NULL;
- struct wlan_network *candidate = NULL;
+ struct wlan_network *pnetwork;
+ struct wlan_network *candidate = NULL;
spin_lock_bh(&pmlmepriv->scanned_queue.lock);
phead = get_list_head(queue);
}
/* check for situation of _FW_LINKED */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ if (check_fwstate(pmlmepriv, _FW_LINKED)) {
DBG_8723A("%s: _FW_LINKED while ask_for_joinbss!!!\n",
__func__);
}
int rtw_set_auth23a(struct rtw_adapter * adapter,
- struct security_priv *psecuritypriv)
+ struct security_priv *psecuritypriv)
{
struct cmd_obj* pcmd;
struct setauth_parm *psetauthparm;
pcmd->rsp = NULL;
pcmd->rspsz = 0;
- INIT_LIST_HEAD(&pcmd->list);
-
RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,
("after enqueue set_auth_cmd, auth_mode=%x\n",
psecuritypriv->dot11AuthAlgrthm));
}
int rtw_set_key23a(struct rtw_adapter *adapter,
- struct security_priv *psecuritypriv, int keyid, u8 set_tx)
+ struct security_priv *psecuritypriv, int keyid, u8 set_tx)
{
u8 keylen;
struct cmd_obj *pcmd;
psetkeyparm->algorithm = (unsigned char)
psecuritypriv->dot118021XGrpPrivacy;
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- ("\n rtw_set_key23a: psetkeyparm->algorithm = (unsigned "
- "char)psecuritypriv->dot118021XGrpPrivacy =%d\n",
- psetkeyparm->algorithm));
+ ("\n 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_,
break;
default:
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- ("\n rtw_set_key23a:psecuritypriv->dot11PrivacyAlgrthm = "
- "%x (must be 1 or 2 or 4 or 5)\n",
+ ("\n rtw_set_key23a:psecuritypriv->dot11PrivacyAlgrthm"
+ " = %x (must be 1 or 2 or 4 or 5)\n",
psecuritypriv->dot11PrivacyAlgrthm));
res = _FAIL;
kfree(pcmd);
pcmd->rsp = NULL;
pcmd->rspsz = 0;
- INIT_LIST_HEAD(&pcmd->list);
-
/* sema_init(&pcmd->cmd_sem, 0); */
res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
unsigned int i, j;
i = 12; /* after the fixed IE */
- while(i < in_len) {
+ while (i < in_len) {
ielength = initial_out_len;
/* WMM element ID and OUI */
i++;
/* continue; */
}
- } while(i < NUM_PMKID_CACHE);
+ } while (i < NUM_PMKID_CACHE);
- if (i == NUM_PMKID_CACHE) {
+ if (i == NUM_PMKID_CACHE)
i = -1;/* Could not find. */
- } else {
+ else {
/* There is one Pre-Authentication Key for
the specific BSSID. */
}
}
return ie_len;
}
+
int rtw_restruct_sec_ie23a(struct rtw_adapter *adapter, u8 *in_ie, u8 *out_ie,
- uint in_len)
+ uint in_len)
{
u8 authmode;
uint ielength;
uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
- ("+rtw_restruct_sec_ie23a: ndisauthmode=%d ndissecuritytype=%d\n",
- ndisauthmode, ndissecuritytype));
+ ("+rtw_restruct_sec_ie23a: ndisauthmode=%d "
+ "ndissecuritytype=%d\n", ndisauthmode, ndissecuritytype));
/* copy fixed ie only */
memcpy(out_ie, in_ie, 12);
ielength = 12;
- if ((ndisauthmode==Ndis802_11AuthModeWPA) ||
- (ndisauthmode==Ndis802_11AuthModeWPAPSK))
- authmode=_WPA_IE_ID_;
- if ((ndisauthmode==Ndis802_11AuthModeWPA2) ||
- (ndisauthmode==Ndis802_11AuthModeWPA2PSK))
- authmode=_WPA2_IE_ID_;
+ if (ndisauthmode == Ndis802_11AuthModeWPA ||
+ ndisauthmode == Ndis802_11AuthModeWPAPSK)
+ authmode = WLAN_EID_VENDOR_SPECIFIC;
+ if (ndisauthmode == Ndis802_11AuthModeWPA2 ||
+ ndisauthmode == Ndis802_11AuthModeWPA2PSK)
+ authmode = _WPA2_IE_ID_;
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==_WPA_IE_ID_) || (authmode==_WPA2_IE_ID_)) {
+ } else if (authmode == WLAN_EID_VENDOR_SPECIFIC ||
+ authmode == _WPA2_IE_ID_) {
/* copy RSN or SSN */
memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0],
psecuritypriv->supplicant_ie[1] + 2);
ielength += psecuritypriv->supplicant_ie[1] + 2;
- rtw_report_sec_ie23a(adapter, authmode,
- psecuritypriv->supplicant_ie);
}
iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
- if (iEntry < 0) {
+ if (iEntry < 0)
return ielength;
- } else {
- if (authmode == _WPA2_IE_ID_) {
- ielength=rtw_append_pmkid(adapter, iEntry,
- out_ie, ielength);
- }
+ else {
+ if (authmode == _WPA2_IE_ID_)
+ ielength = rtw_append_pmkid(adapter, iEntry,
+ out_ie, ielength);
}
return ielength;
pdev_network->IELength = sz;
pdev_network->Length =
- get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network);
+ 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); */
-
}
void rtw_get_encrypt_decrypt_from_registrypriv23a(struct rtw_adapter* adapter)
threshold = 1;
else
threshold = 0;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_RXDMA_AGG_PG_TH,
- (u8 *)(&threshold));
- } else {
+ } else
threshold = 1;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_RXDMA_AGG_PG_TH,
- (u8 *)(&threshold));
- }
+
+ rtl8723a_set_rxdma_agg_pg_th(padapter, threshold);
}
/* the fucntion is >= passive_level */
unsigned int rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
- u8 *out_ie, uint in_len, uint *pout_len)
+ u8 *out_ie, uint in_len, uint *pout_len)
{
- u32 ielen, out_len;
+ u32 out_len;
int max_rx_ampdu_factor;
- unsigned char *p, *pframe;
+ unsigned char *pframe;
+ const u8 *p;
struct ieee80211_ht_cap ht_capie;
unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
phtpriv->ht_option = false;
- p = rtw_get_ie23a(in_ie + 12, _HT_CAPABILITY_IE_, &ielen, in_len - 12);
+ p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, in_ie + 12, in_len -12);
- if (p && ielen > 0) {
+ if (p && p[1] > 0) {
u32 rx_packet_offset, max_recvbuf_sz;
if (pqospriv->qos_option == 0) {
out_len = *pout_len;
pframe = rtw_set_ie23a(out_ie + out_len,
- _VENDOR_SPECIFIC_IE_,
+ WLAN_EID_VENDOR_SPECIFIC,
_WMM_IE_Length_, WMM_IE, pout_len);
pqospriv->qos_option = 1;
ht_capie.ampdu_params_info |=
(IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00);
- pframe = rtw_set_ie23a(out_ie + out_len, _HT_CAPABILITY_IE_,
+ 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 = rtw_get_ie23a(in_ie + 12, _HT_ADD_INFO_IE_, &ielen, in_len-12);
- if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, in_ie + 12,
+ in_len -12);
+ if (p && (p[1] == sizeof(struct ieee80211_ht_addt_info))) {
out_len = *pout_len;
- pframe = rtw_set_ie23a(out_ie + out_len, _HT_ADD_INFO_IE_,
- ielen, p + 2 , pout_len);
+ pframe = rtw_set_ie23a(out_ie + out_len,
+ WLAN_EID_HT_OPERATION,
+ p[1], p + 2 , pout_len);
}
}
/* the fucntion is > passive_level (in critical_section) */
void rtw_update_ht_cap23a(struct rtw_adapter *padapter, u8 *pie, uint ie_len)
{
- u8 *p, max_ampdu_sz;
- int len;
- /* struct sta_info *bmc_sta, *psta; */
+ u8 max_ampdu_sz;
+ const u8 *p;
struct ieee80211_ht_cap *pht_capie;
struct ieee80211_ht_addt_info *pht_addtinfo;
- /* struct recv_reorder_ctrl *preorder_ctrl; */
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct ht_priv *phtpriv = &pmlmepriv->htpriv;
- /* struct recv_priv *precvpriv = &padapter->recvpriv; */
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct ht_priv *phtpriv = &pmlmepriv->htpriv;
struct registry_priv *pregistrypriv = &padapter->registrypriv;
- /* struct wlan_network *pcur_network = &pmlmepriv->cur_network;; */
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
if (!phtpriv->ht_option)
DBG_8723A("+rtw_update_ht_cap23a()\n");
+ /* Adjust pie + ie_len for our searches */
+ pie += sizeof (struct ndis_802_11_fixed_ies);
+ ie_len -= sizeof (struct ndis_802_11_fixed_ies);
+
/* maybe needs check if ap supports rx ampdu. */
- if ((phtpriv->ampdu_enable == false) && (pregistrypriv->ampdu_enable == 1)) {
+ if (phtpriv->ampdu_enable == false &&
+ pregistrypriv->ampdu_enable == 1) {
if (pregistrypriv->wifi_spec == 1)
phtpriv->ampdu_enable = false;
else
phtpriv->ampdu_enable = true;
- } else if (pregistrypriv->ampdu_enable == 2) {
+ } else if (pregistrypriv->ampdu_enable == 2)
phtpriv->ampdu_enable = true;
- }
/* check Max Rx A-MPDU Size */
- len = 0;
- p = rtw_get_ie23a(pie+sizeof (struct ndis_802_11_fixed_ies), _HT_CAPABILITY_IE_, &len, ie_len-sizeof (struct ndis_802_11_fixed_ies));
- if (p && len > 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 = 1 << (max_ampdu_sz+3); /* max_ampdu_sz (kbytes); */
-
- /* DBG_8723A("rtw_update_ht_cap23a(): max_ampdu_sz =%d\n", max_ampdu_sz); */
- phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
+ 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;
}
- len = 0;
- p = rtw_get_ie23a(pie+sizeof (struct ndis_802_11_fixed_ies), _HT_ADD_INFO_IE_, &len, ie_len-sizeof (struct ndis_802_11_fixed_ies));
- if (p && len>0)
- {
- pht_addtinfo = (struct ieee80211_ht_addt_info *)(p+2);
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pie, ie_len);
+ if (p && p[1] > 0) {
+ pht_addtinfo = (struct ieee80211_ht_addt_info *)(p + 2);
/* todo: */
}
/* update cur_bwmode & cur_ch_offset */
- if ((pregistrypriv->cbw40_enable) &&
- (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) &&
- (pmlmeinfo->HT_info.infos[0] & BIT(2)))
- {
+ if (pregistrypriv->cbw40_enable &&
+ pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1) &&
+ pmlmeinfo->HT_info.infos[0] & BIT(2)) {
int i;
- u8 rf_type;
+ u8 rf_type;
- padapter->HalFunc.GetHwRegHandler(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+ rf_type = rtl8723a_get_rf_type(padapter);
/* update the MCS rates */
- for (i = 0; i < 16; i++)
- {
- if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R))
+ 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_1R23A[i];
else
pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R23A[i];
pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
switch ((pmlmeinfo->HT_info.infos[0] & 0x3))
{
- case HT_EXTCHNL_OFFSET_UPPER:
- pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
- break;
+ case HT_EXTCHNL_OFFSET_UPPER:
+ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
+ break;
- case HT_EXTCHNL_OFFSET_LOWER:
- pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
- break;
+ case HT_EXTCHNL_OFFSET_LOWER:
+ pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
+ break;
- default:
- pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- break;
+ default:
+ pmlmeext->cur_ch_offset =
+ HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+ break;
}
}
/* */
/* Config SM Power Save setting */
/* */
- pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
+ pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &
+ 0x0C) >> 2;
if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
}
-void rtw_issue_addbareq_cmd23a(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe)
+void rtw_issue_addbareq_cmd23a(struct rtw_adapter *padapter,
+ struct xmit_frame *pxmitframe)
{
u8 issued;
int priority;
- struct sta_info *psta = NULL;
+ 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))
+ if (bmcst || padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100)
return;
priority = pattrib->priority;
if (pattrib->psta)
psta = pattrib->psta;
- else
- {
+ else {
DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra);
}
- if (psta == NULL)
- {
+ 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);
+ 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 == true) && (phtpriv->ampdu_enable == true))
- {
+ if (phtpriv->ht_option == true && phtpriv->ampdu_enable == true) {
issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
- if (0 == issued)
- {
- DBG_8723A("rtw_issue_addbareq_cmd23a, p =%d\n", priority);
- psta->htpriv.candidate_tid_bitmap |= CHKBIT((u8)priority);
- rtw_addbareq_cmd23a(padapter, (u8) priority, pattrib->ra);
- }
- }
-}
-
-inline 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;
-}
-
-inline u8 rtw_to_roaming(struct rtw_adapter *adapter)
-{
- return adapter->mlmepriv.to_roaming;
-}
-
-void rtw23a_roaming(struct rtw_adapter *padapter, struct wlan_network *tgt_network)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- spin_lock_bh(&pmlmepriv->lock);
- _rtw23a_roaming(padapter, tgt_network);
- spin_unlock_bh(&pmlmepriv->lock);
-}
-void _rtw23a_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 != NULL)
- pnetwork = tgt_network;
- else
- pnetwork = &pmlmepriv->cur_network;
-
- if (0 < rtw_to_roaming(padapter)) {
- DBG_8723A("roaming from %s("MAC_FMT"), length:%d\n",
- pnetwork->network.Ssid.ssid,
- MAC_ARG(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) {
- if (_SUCCESS == (do_join_r = rtw_do_join23a(padapter))) {
- break;
- } else {
- DBG_8723A("roaming do_join return %d\n", do_join_r);
- pmlmepriv->to_roaming--;
-
- if (0 < rtw_to_roaming(padapter)) {
- continue;
- } else {
- DBG_8723A("%s(%d) -to roaming fail, indicate_disconnect\n", __func__, __LINE__);
- rtw_indicate_disconnect23a(padapter);
- break;
- }
- }
+ if (issued == 0) {
+ DBG_8723A("rtw_issue_addbareq_cmd23a, p =%d\n",
+ priority);
+ psta->htpriv.candidate_tid_bitmap |=
+ CHKBIT((u8)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 (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) == true)
+ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED))
return true;
}
return false;
#include <wlan_bssdef.h>
#include <mlme_osdep.h>
#include <recv_osdep.h>
-#include <ethernet.h>
#include <linux/ieee80211.h>
#ifdef CONFIG_8723AU_BT_COEXIST
#include <rtl8723a_hal.h>
#endif
+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 OnAuth23a(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 struct mlme_handler mlme_sta_tbl[]={
{"OnAssocReq23a", &OnAssocReq23a},
{"OnAssocRsp23a", &OnAssocRsp23a},
/**************************************************
OUI definitions for the vendor specific IE
***************************************************/
-unsigned char RTW_WPA_OUI23A[] = {0x00, 0x50, 0xf2, 0x01};
unsigned char WMM_OUI23A[] = {0x00, 0x50, 0xf2, 0x02};
unsigned char WPS_OUI23A[] = {0x00, 0x50, 0xf2, 0x04};
unsigned char P2P_OUI23A[] = {0x50, 0x6F, 0x9A, 0x09};
};
+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
channel_list->reg_classes = cla;
}
-static u8 init_channel_set(struct rtw_adapter* padapter, u8 ChannelPlan,
- struct rt_channel_info *channel_set)
+static u8 init_channel_set(struct rtw_adapter* padapter, u8 cplan,
+ struct rt_channel_info *c_set)
{
- u8 index, chanset_size = 0;
- u8 b5GBand = false, b2_4GBand = false;
- u8 Index2G = 0, Index5G = 0;
+ u8 i, ch_size = 0;
+ u8 b5GBand = false, b2_4GBand = false;
+ u8 Index2G = 0, Index5G = 0;
- memset(channel_set, 0, sizeof(struct rt_channel_info)*MAX_CHANNEL_NUM);
+ memset(c_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM);
- if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX &&
- ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
- DBG_8723A("ChannelPlan ID %x error !!!!!\n", ChannelPlan);
- return chanset_size;
+ 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 == ChannelPlan)
+ if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
else
- Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
+ Index2G = RTW_ChannelPlanMap[cplan].Index2G;
}
if (padapter->registrypriv.wireless_mode & WIRELESS_11A) {
b5GBand = true;
- if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
+ if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
else
- Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
+ Index5G = RTW_ChannelPlanMap[cplan].Index5G;
}
if (b2_4GBand) {
- for (index = 0; index<RTW_ChannelPlan2G[Index2G].Len; index++) {
- channel_set[chanset_size].ChannelNum =
- RTW_ChannelPlan2G[Index2G].Channel[index];
+ 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 == ChannelPlan) ||
+ if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == cplan) ||
/* Channel 1~11 is active, and 12~14 is passive */
- (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == ChannelPlan)){
- if (channel_set[chanset_size].ChannelNum >= 1 &&
- channel_set[chanset_size].ChannelNum <= 11)
- channel_set[chanset_size].ScanType =
- SCAN_ACTIVE;
- else if ((channel_set[chanset_size].ChannelNum >= 12 &&
- channel_set[chanset_size].ChannelNum <= 14))
- channel_set[chanset_size].ScanType =
- SCAN_PASSIVE;
- } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 ==
- ChannelPlan ||
- RT_CHANNEL_DOMAIN_WORLD_WIDE_5G ==
- ChannelPlan ||
+ 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 (channel_set[chanset_size].ChannelNum <= 11)
- channel_set[chanset_size].ScanType =
- SCAN_ACTIVE;
+ if (c_set[ch_size].ChannelNum <= 11)
+ c_set[ch_size].ScanType = SCAN_ACTIVE;
else
- channel_set[chanset_size].ScanType =
- SCAN_PASSIVE;
+ c_set[ch_size].ScanType = SCAN_PASSIVE;
} else
- channel_set[chanset_size].ScanType =
- SCAN_ACTIVE;
+ c_set[ch_size].ScanType = SCAN_ACTIVE;
- chanset_size++;
+ ch_size++;
}
}
if (b5GBand) {
- for (index = 0;index<RTW_ChannelPlan5G[Index5G].Len;index++) {
- if (RTW_ChannelPlan5G[Index5G].Channel[index] <= 48 ||
- RTW_ChannelPlan5G[Index5G].Channel[index] >= 149) {
- channel_set[chanset_size].ChannelNum =
- RTW_ChannelPlan5G[Index5G].Channel[index];
- if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G ==
- ChannelPlan) {
+ 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 */
- channel_set[chanset_size].ScanType =
+ c_set[ch_size].ScanType =
SCAN_PASSIVE;
} else
- channel_set[chanset_size].ScanType =
+ c_set[ch_size].ScanType =
SCAN_ACTIVE;
DBG_8723A("%s(): channel_set[%d].ChannelNum = "
- "%d\n", __func__, chanset_size,
- channel_set[chanset_size].ChannelNum);
- chanset_size++;
+ "%d\n", __func__, ch_size,
+ c_set[ch_size].ChannelNum);
+ ch_size++;
}
}
}
- return chanset_size;
+ return ch_size;
}
int init_mlme_ext_priv23a(struct rtw_adapter* padapter)
void mgt_dispatcher23a(struct rtw_adapter *padapter,
struct recv_frame *precv_frame)
{
- int index;
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_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u16 stype;
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
struct sta_info *psta;
+ u16 stype;
+ int index;
- if (!ieee80211_is_mgmt(hdr->frame_control))
+ 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(hdr->addr1, myid(&padapter->eeprompriv)) &&
- !is_broadcast_ether_addr(hdr->addr1))
+ if (!ether_addr_equal(mgmt->da, myid(&padapter->eeprompriv)) &&
+ !is_broadcast_ether_addr(mgmt->da))
return;
ptable = mlme_sta_tbl;
- stype = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE;
+ stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
index = stype >> 4;
if (index > 13) {
}
ptable += index;
- psta = rtw_get_stainfo23a(&padapter->stapriv, hdr->addr2);
+ psta = rtw_get_stainfo23a(&padapter->stapriv, mgmt->sa);
if (psta) {
- if (ieee80211_has_retry(hdr->frame_control)) {
+ if (ieee80211_has_retry(mgmt->frame_control)) {
if (precv_frame->attrib.seq_num ==
psta->RxMgmtFrameSeqNum) {
/* drop the duplicate management frame */
break;
default:
_mgt_dispatcher23a(padapter, ptable, precv_frame);
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
- rtw_hostapd_mlme_rx23a(padapter, precv_frame);
break;
}
#else
#endif
}
-#ifdef CONFIG_8723AU_P2P
-static u32 p2p_listen_state_process(struct rtw_adapter *padapter,
- unsigned char *da)
-{
- bool response = true;
-
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == false ||
- padapter->mlmepriv.wps_probe_resp_ie == NULL ||
- padapter->mlmepriv.p2p_probe_resp_ie == NULL) {
- DBG_8723A("DON'T issue_probersp23a_p2p23a: p2p_enabled:%d, "
- "wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n",
- wdev_to_priv(padapter->rtw_wdev)->p2p_enabled,
- padapter->mlmepriv.wps_probe_resp_ie,
- padapter->mlmepriv.p2p_probe_resp_ie);
- response = false;
- }
-
- if (response == true)
- issue_probersp23a_p2p23a(padapter, da);
-
- return _SUCCESS;
-}
-#endif /* CONFIG_8723AU_P2P */
-
/****************************************************************************
Following are the callback functions for each subtype of the management frames
*****************************************************************************/
-unsigned int OnProbeReq23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
+static int
+OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
- unsigned int ielen;
- unsigned char *p;
+ 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_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u8 *pframe = skb->data;
- uint len = skb->len;
- u8 is_valid_p2p_probereq = false;
-
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 wifi_test_chk_rate = 1;
-
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
- !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
- !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
- !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
- !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)) {
- /* mcs_rate = 0 -> CCK 1M rate */
- /* mcs_rate = 1 -> CCK 2M rate */
- /* mcs_rate = 2 -> CCK 5.5M rate */
- /* mcs_rate = 3 -> CCK 11M rate */
- /* In the P2P mode, the driver should not support
- the CCK rate */
-
- /* IOT issue: Google Nexus7 use 1M rate to send
- p2p_probe_req after GO nego completed and Nexus7
- is client */
- if (wifi_test_chk_rate == 1) {
- if ((is_valid_p2p_probereq =
- process_probe_req_p2p_ie23a(pwdinfo, pframe,
- len)) == true) {
- if (rtw_p2p_chk_role(pwdinfo,
- P2P_ROLE_DEVICE)) {
- u8 *sa = ieee80211_get_SA(hdr);
- p2p_listen_state_process(padapter, sa);
- return _SUCCESS;
- }
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- goto _continue;
- }
- }
- }
- }
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
+ int len = skb->len;
-_continue:
-#endif /* CONFIG_8723AU_P2P */
-
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
return _SUCCESS;
- }
- if (check_fwstate(pmlmepriv, _FW_LINKED) == false &&
- check_fwstate(pmlmepriv,
- WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == false) {
+ if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
+ !check_fwstate(pmlmepriv,
+ WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
return _SUCCESS;
- }
- p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) +
- _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
- len - sizeof(struct ieee80211_hdr_3addr) -
- _PROBEREQ_IE_OFFSET_);
+ if (unlikely(!ieee80211_is_probe_req(mgmt->frame_control))) {
+ printk(KERN_WARNING "%s: Received non probe request frame\n",
+ __func__);
+ return _FAIL;
+ }
- /* check (wildcard) SSID */
- if (p) {
- if (is_valid_p2p_probereq == true) {
- goto _issue_probersp23a;
- }
+ len -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
- if ((ielen != 0 &&
- memcmp((void *)(p+2), cur->Ssid.ssid,
- cur->Ssid.ssid_len)) ||
- (ielen == 0 && pmlmeinfo->hidden_ssid_mode)) {
- return _SUCCESS;
- }
+ ie = cfg80211_find_ie(WLAN_EID_SSID, mgmt->u.probe_req.variable, len);
-_issue_probersp23a:
+ /* check (wildcard) SSID */
+ if (!ie)
+ goto out;
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true &&
- pmlmepriv->cur_network.join_res == true) {
- /* DBG_8723A("+issue_probersp23a during ap mode\n"); */
- issue_probersp23a(padapter, ieee80211_get_SA(hdr),
- is_valid_p2p_probereq);
- }
+ 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_probersp23a(padapter, mgmt->sa, false);
+
+out:
return _SUCCESS;
}
-unsigned int OnProbeRsp23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
+static int
+OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-#ifdef CONFIG_8723AU_P2P
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif
-
-#ifdef CONFIG_8723AU_P2P
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
- if (pwdinfo->tx_prov_disc_info.benable == true) {
- if (ether_addr_equal(pwdinfo->tx_prov_disc_info.peerIFAddr,
- hdr->addr2)) {
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
- pwdinfo->tx_prov_disc_info.benable = false;
- issue_p2p_provision_request23a(padapter,
- pwdinfo->tx_prov_disc_info.ssid.ssid,
- pwdinfo->tx_prov_disc_info.ssid.ssid_len,
- pwdinfo->tx_prov_disc_info.peerDevAddr);
- }
- else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- {
- pwdinfo->tx_prov_disc_info.benable = false;
- issue_p2p_provision_request23a(padapter,
- NULL,
- 0,
- pwdinfo->tx_prov_disc_info.peerDevAddr);
- }
- }
- }
- return _SUCCESS;
- } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
- if (pwdinfo->nego_req_info.benable == true) {
- DBG_8723A("[%s] P2P State is GONEGO ING!\n", __func__);
- if (ether_addr_equal(pwdinfo->nego_req_info.peerDevAddr,
- hdr->addr2)) {
- pwdinfo->nego_req_info.benable = false;
- issue_p2p_GO_request23a(padapter, pwdinfo->nego_req_info.peerDevAddr);
- }
- }
- } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
- if (pwdinfo->invitereq_info.benable == true) {
- DBG_8723A("[%s] P2P_STATE_TX_INVITE_REQ!\n", __func__);
- if (ether_addr_equal(
- pwdinfo->invitereq_info.peer_macaddr,
- hdr->addr2)) {
- pwdinfo->invitereq_info.benable = false;
- issue_p2p_invitation_request23a(padapter, pwdinfo->invitereq_info.peer_macaddr);
- }
- }
- }
-#endif
if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
report_survey_event23a(padapter, precv_frame);
return _SUCCESS;
}
-unsigned int OnBeacon23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
+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_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_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
u8 *pframe = skb->data;
- uint len = skb->len;
+ int pkt_len = skb->len;
struct wlan_bssid_ex *pbss;
int ret = _SUCCESS;
- u8 *p = NULL;
+ u8 *p, *pie;
+ int pie_len;
u32 ielen = 0;
- p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) +
- _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen,
- len - sizeof(struct ieee80211_hdr_3addr) -
- _BEACON_IE_OFFSET_);
- if ((p != NULL) && (ielen > 0)) {
- if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D)) {
+ 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",
- hdr->addr3);
- *(p + 1) = ielen - 1;
+ mgmt->bssid);
+ p[1] = ielen - 1;
}
}
return _SUCCESS;
}
- if (ether_addr_equal(hdr->addr3, get_my_bssid23a(&pmlmeinfo->network))){
- if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
- /* we should update current network before auth,
- or some IE is wrong */
- pbss = (struct wlan_bssid_ex *)
- kmalloc(sizeof(struct wlan_bssid_ex),
- GFP_ATOMIC);
- if (pbss) {
- if (collect_bss_info23a(padapter, precv_frame,
- pbss) == _SUCCESS) {
- update_network23a(&pmlmepriv->cur_network.network, pbss, padapter, true);
- rtw_get_bcn_info23a(&pmlmepriv->cur_network);
- }
- kfree(pbss);
- }
+ if (!ether_addr_equal(mgmt->bssid,
+ get_my_bssid23a(&pmlmeinfo->network)))
+ goto out;
- /* check the vendor of the assoc AP */
- pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pframe + sizeof(struct ieee80211_hdr_3addr), len-sizeof(struct ieee80211_hdr_3addr));
+ if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
+ /* we should update current network before auth,
+ or some IE is wrong */
+ pbss = (struct wlan_bssid_ex *)
+ kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
+ if (pbss) {
+ if (collect_bss_info23a(padapter, precv_frame, pbss) ==
+ _SUCCESS) {
+ update_network23a(
+ &pmlmepriv->cur_network.network, pbss,
+ padapter, true);
+ rtw_get_bcn_info23a(&pmlmepriv->cur_network);
+ }
+ kfree(pbss);
+ }
- /* update TSF Value */
- update_TSF23a(pmlmeext, pframe, len);
+ /* 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));
- /* start auth */
- start_clnt_auth23a(padapter);
+ /* update TSF Value */
+ rtw_update_TSF(pmlmeext, mgmt);
- return _SUCCESS;
- }
+ /* start auth */
+ start_clnt_auth23a(padapter);
- if (((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) &&
- (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
- psta = rtw_get_stainfo23a(pstapriv, hdr->addr2);
- if (psta) {
- ret = rtw_check_bcn_info23a(padapter, pframe,
- len);
- if (!ret) {
- 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, pframe,
- len, psta);
- }
+ return _SUCCESS;
+ }
-#ifdef CONFIG_8723AU_P2P
- process_p2p_ps_ie23a(padapter, (pframe + sizeof(struct ieee80211_hdr_3addr)), (len - sizeof(struct ieee80211_hdr_3addr)));
-#endif /* CONFIG_8723AU_P2P */
+ if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) &&
+ (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) {
+ 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, pframe,
+ pkt_len, psta);
+ }
+ }
+ } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
+ 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, pframe,
+ 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;
}
- } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
- psta = rtw_get_stainfo23a(pstapriv, hdr->addr2);
- 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, pframe,
- len, psta);
- }
- } else {
- /* allocate a new CAM entry for IBSS station */
- cam_idx = allocate_fw_sta_entry23a(padapter);
- if (cam_idx == NUM_STA)
- goto _END_ONBEACON_;
-
- /* get supported rate */
- if (update_sta_support_rate23a(padapter, (pframe + sizeof(struct ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_), (len - sizeof(struct ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_), cam_idx) == _FAIL) {
- pmlmeinfo->FW_sta_info[cam_idx].status = 0;
- goto _END_ONBEACON_;
- }
- /* update TSF Value */
- update_TSF23a(pmlmeext, pframe, len);
+ /* update TSF Value */
+ rtw_update_TSF(pmlmeext, mgmt);
- /* report sta add event */
- report_add_sta_event23a(padapter, hdr->addr2,
- cam_idx);
- }
+ /* report sta add event */
+ report_add_sta_event23a(padapter, mgmt->sa,
+ cam_idx);
}
}
-_END_ONBEACON_:
+out:
return _SUCCESS;
}
-unsigned int OnAuth23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
+static int
+OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
#ifdef CONFIG_8723AU_AP_MODE
- unsigned int auth_mode, seq, ie_len;
- unsigned char *sa, *p;
- u16 algorithm;
- int status;
static struct sta_info stat;
- struct sta_info *pstat = NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
+ 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_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u8 *pframe = skb->data;
- uint len = skb->len;
+ 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) != WIFI_FW_AP_STATE)
+ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
return _FAIL;
DBG_8723A("+OnAuth23a\n");
- sa = hdr->addr2;
+ sa = mgmt->sa;
auth_mode = psecuritypriv->dot11AuthAlgrthm;
- seq = cpu_to_le16(*(u16*)((unsigned long)pframe +
- sizeof(struct ieee80211_hdr_3addr) + 2));
- algorithm = cpu_to_le16(*(u16*)((unsigned long)pframe +
- sizeof(struct ieee80211_hdr_3addr)));
+
+ 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);
/* rx a shared-key auth but shared not enabled, or */
/* rx a open-system auth but shared-key is enabled */
- if ((algorithm > 0 && auth_mode == 0) ||
- (algorithm == 0 && auth_mode == 1)) {
+ 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,
if (!list_empty(&pstat->asoc_list)) {
list_del_init(&pstat->asoc_list);
pstapriv->asoc_list_cnt--;
- if (pstat->expire_to > 0)
- {
+ if (pstat->expire_to > 0) {
/* TODO: STA re_auth within expire_to */
}
}
goto auth_fail;
}
- if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2)) {
+ 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;
/* checking for challenging txt... */
DBG_8723A("checking for challenging txt...\n");
- p = rtw_get_ie23a(pframe +
- sizeof(struct ieee80211_hdr_3addr) +
- 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_,
- (int *)&ie_len, len -
- sizeof(struct ieee80211_hdr_3addr) -
- _AUTH_IE_OFFSET_ - 4);
-
- if ((p == NULL) || (ie_len<= 0)) {
+ 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((void *)(p + 2), pstat->chg_txt, 128)) {
- pstat->state &= (~WIFI_FW_AUTH_STATE);
+ 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;
/* Now, we are going to issue_auth23a... */
pstat->auth_seq = seq + 1;
- issue_auth23a(padapter, pstat, (unsigned short)WLAN_STATUS_SUCCESS);
+ issue_auth23a(padapter, pstat, WLAN_STATUS_SUCCESS);
if (pstat->state & WIFI_FW_AUTH_SUCCESS)
pstat->auth_seq = 0;
return _FAIL;
}
-unsigned int OnAuth23aClient23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
+static int
+OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
- unsigned int seq, len, status, algthm, offset;
- unsigned char *p;
- unsigned int go2asoc = 0;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ 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_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u8 *pframe = skb->data;
- uint pkt_len = skb->len;
+ 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),
- ieee80211_get_DA(hdr)))
+ if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
return _SUCCESS;
if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
return _SUCCESS;
- offset = ieee80211_has_protected(hdr->frame_control) ? 4: 0;
+ pie = mgmt->u.auth.variable;
+ plen -= offsetof(struct ieee80211_mgmt, u.auth.variable);
- algthm = le16_to_cpu(*(unsigned short *)((unsigned long)pframe + sizeof(struct ieee80211_hdr_3addr) + offset));
- seq = le16_to_cpu(*(unsigned short *)((unsigned long)pframe + sizeof(struct ieee80211_hdr_3addr) + offset + 2));
- status = le16_to_cpu(*(unsigned short *)((unsigned long)pframe + sizeof(struct ieee80211_hdr_3addr) + offset + 4));
+ 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 != 0)
- {
+ if (status) {
DBG_8723A("clnt auth fail, status: %d\n", status);
- if (status == 13)/* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
- {
+ /* 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
goto authclnt_fail;
}
- if (seq == 2)
- {
- if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
- {
- /* legendary shared system */
- p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
- pkt_len - sizeof(struct ieee80211_hdr_3addr) - _AUTH_IE_OFFSET_);
+ if (seq == 2) {
+ if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
+ /* legendary shared system */
+ p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pie, plen);
- if (p == NULL)
- {
+ if (!p) {
/* DBG_8723A("marc: no challenge text?\n"); */
goto authclnt_fail;
}
- memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
+ memcpy((void *)(pmlmeinfo->chg_txt), p + 2, p[1]);
pmlmeinfo->auth_seq = 3;
issue_auth23a(padapter, NULL, 0);
set_link_timer(pmlmeext, REAUTH_TO);
return _SUCCESS;
- }
- else
- {
+ } else {
/* open system */
go2asoc = 1;
}
- }
- else if (seq == 4)
- {
+ } else if (seq == 4) {
if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
- {
go2asoc = 1;
- }
else
- {
goto authclnt_fail;
- }
- }
- else
- {
+ } else {
/* this is also illegal */
- /* DBG_8723A("marc: clnt auth failed due to illegal seq =%x\n", seq); */
+ /* DBG_8723A("marc: clnt auth failed due to illegal seq =%x\n",
+ seq); */
goto authclnt_fail;
}
- if (go2asoc)
- {
+ if (go2asoc) {
DBG_8723A_LEVEL(_drv_always_, "auth success, start assoc\n");
start_clnt_assoc23a(padapter);
return _SUCCESS;
return _FAIL;
}
-unsigned int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
+#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 1:
+ /* Microsoft OUI (00:50:F2) with OUI Type 1:
+ * real WPA information element */
+ break;
+ case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */
+ 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 4:
+ /* 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:
+ 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 rtw_ieee802_11_elems elems;
struct sta_info *pstat;
- unsigned char reassoc, *p, *pos, *wpa_ie;
+ unsigned char reassoc;
unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
- int i, ie_len, wpa_ie_len, left;
- unsigned char supportRate[16];
- int supportRateNum;
- unsigned short status = WLAN_STATUS_SUCCESS;
- unsigned short ie_offset;
+ 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 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;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u16 frame_control;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 p2p_status_code = P2P_STATUS_SUCCESS;
- u8 *p2pie;
- u32 p2pielen = 0;
- u8 wfd_ie[ 128 ] = { 0x00 };
- u32 wfd_ielen = 0;
-#endif /* CONFIG_8723AU_P2P */
+ int r;
- if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
+ if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
return _FAIL;
- frame_control = hdr->frame_control;
- if (ieee80211_is_assoc_req(frame_control)) {
+ left = pkt_len - sizeof(struct ieee80211_hdr_3addr);
+ if (ieee80211_is_assoc_req(mgmt->frame_control)) {
reassoc = 0;
- ie_offset = _ASOCREQ_IE_OFFSET_;
+ pos = mgmt->u.assoc_req.variable;
+ left -= offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
} else { /* WIFI_REASSOCREQ */
reassoc = 1;
- ie_offset = _REASOCREQ_IE_OFFSET_;
+ pos = mgmt->u.reassoc_req.variable;
+ left -= offsetof(struct ieee80211_mgmt, u.reassoc_req.variable);
}
- if (pkt_len < sizeof(struct ieee80211_hdr_3addr) + ie_offset) {
- DBG_8723A("handle_assoc(reassoc =%d) - too short payload (len =%lu)"
- "\n", reassoc, (unsigned long)pkt_len);
+ 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, hdr->addr2);
+ pstat = rtw_get_stainfo23a(pstapriv, mgmt->sa);
if (!pstat) {
status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
goto asoc_class2_error;
}
- capab_info = get_unaligned_le16(pframe + sizeof(struct ieee80211_hdr_3addr));
- /* capab_info = le16_to_cpu(*(unsigned short *)(pframe + sizeof(struct ieee80211_hdr_3addr))); */
- /* listen_interval = le16_to_cpu(*(unsigned short *)(pframe + sizeof(struct ieee80211_hdr_3addr)+2)); */
- listen_interval = get_unaligned_le16(pframe + sizeof(struct ieee80211_hdr_3addr)+2);
-
- left = pkt_len - (sizeof(struct ieee80211_hdr_3addr) + ie_offset);
- pos = pframe + (sizeof(struct ieee80211_hdr_3addr) + ie_offset);
+ /* 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))
- {
+ 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
- {
+ } else {
pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
pstat->state |= WIFI_FW_ASSOC_STATE;
}
- }
- else
- {
+ } 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_ieee802_11_parse_elems23a(pos, left, &elems, 1) == ParseFailed ||
- !elems.ssid) {
+
+ if (rtw_validate_frame_ies(pos, left)) {
DBG_8723A("STA " MAC_FMT " sent invalid association request\n",
- MAC_ARG(pstat->hwaddr));
+ MAC_ARG(pstat->hwaddr));
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto OnAssocReq23aFail;
}
/* now we should check all the fields... */
/* checking SSID */
- p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset, _SSID_IE_, &ie_len,
- pkt_len - sizeof(struct ieee80211_hdr_3addr) - ie_offset);
- if (p == NULL)
- {
- status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- }
-
- if (ie_len == 0) /* broadcast ssid, however it is not allowed in assocreq */
+ 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 " MAC_FMT " sent invalid association request "
+ "lacking an SSID\n", MAC_ARG(pstat->hwaddr));
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- else {
+ goto OnAssocReq23aFail;
+ } else {
/* check if ssid match */
- if (memcmp((void *)(p+2), cur->Ssid.ssid, cur->Ssid.ssid_len))
+ if (memcmp(p + 2, cur->Ssid.ssid, cur->Ssid.ssid_len))
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- if (ie_len != cur->Ssid.ssid_len)
+ if (p[1] != cur->Ssid.ssid_len)
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
}
- if (WLAN_STATUS_SUCCESS != status)
+ if (status != WLAN_STATUS_SUCCESS)
goto OnAssocReq23aFail;
/* check if the supported rate is ok */
- p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - sizeof(struct ieee80211_hdr_3addr) - ie_offset);
- if (p == NULL) {
- DBG_8723A("Rx a sta assoc-req which supported rate is empty!\n");
+ 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, ie_len);
- supportRateNum = ie_len;
-
- p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len,
- pkt_len - sizeof(struct ieee80211_hdr_3addr) - ie_offset);
- if (p != NULL) {
-
- if (supportRateNum<= sizeof(supportRate))
- {
- memcpy(supportRate+supportRateNum, p+2, ie_len);
- supportRateNum += ie_len;
+ 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];
}
}
}
pstat->wpa_pairwise_cipher = 0;
pstat->wpa2_pairwise_cipher = 0;
memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
- if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_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 = elems.rsn_ie;
- wpa_ie_len = elems.rsn_ie_len;
-
- if (rtw_parse_wpa2_ie23a(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _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;
-
- if (!pstat->wpa2_group_cipher)
- status = WLAN_REASON_INVALID_GROUP_CIPHER;
-
- if (!pstat->wpa2_pairwise_cipher)
- status = WLAN_REASON_INVALID_PAIRWISE_CIPHER;
+ 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 {
- status = WLAN_STATUS_INVALID_IE;
+ wpa_ie = NULL;
+ wpa_ie_len = 0;
}
-
- } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
-
- int group_cipher = 0, pairwise_cipher = 0;
-
- wpa_ie = elems.wpa_ie;
- wpa_ie_len = elems.wpa_ie_len;
-
- if (rtw_parse_wpa_ie23a(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _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;
-
+ 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;
-
- } else {
- status = WLAN_STATUS_INVALID_IE;
}
-
- } else {
- wpa_ie = NULL;
- wpa_ie_len = 0;
}
- if (WLAN_STATUS_SUCCESS != status)
+ if (status != WLAN_STATUS_SUCCESS)
goto OnAssocReq23aFail;
pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
- if (wpa_ie == NULL) {
- if (elems.wps_ie) {
- DBG_8723A("STA included WPS IE in "
- "(Re)Association Request - assume WPS is "
- "used\n");
+
+ 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");
+ DBG_8723A("STA did not include WPA/RSN IE in (Re)"
+ "Association Request - possible WPS use\n");
pstat->flags |= WLAN_STA_MAYBE_WPS;
}
- /* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */
+ /* AP support WPA/RSN, and sta is going to do WPS, but AP
+ is not ready */
/* that the selected registrar of AP is _FLASE */
- if ((psecuritypriv->wpa_psk > 0) &&
- (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) {
+ if (psecuritypriv->wpa_psk > 0 &&
+ pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)) {
if (pmlmepriv->wps_beacon_ie) {
u8 selected_registrar = 0;
- rtw_get_wps_attr_content23a(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len,
- WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL);
+ rtw_get_wps_attr_content23a(
+ pmlmepriv->wps_beacon_ie,
+ pmlmepriv->wps_beacon_ie_len,
+ WPS_ATTR_SELECTED_REGISTRAR,
+ &selected_registrar, NULL);
if (!selected_registrar) {
- DBG_8723A("selected_registrar is false , or AP is not ready to do WPS\n");
+ DBG_8723A("selected_registrar is false,"
+ "or AP is not ready to do "
+ "WPS\n");
status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
-
goto OnAssocReq23aFail;
}
}
if (psecuritypriv->wpa_psk == 0) {
DBG_8723A("STA " MAC_FMT ": WPA/RSN IE in association "
- "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
+ "request, but AP don't support WPA/RSN\n",
+ MAC_ARG(pstat->hwaddr));
status = WLAN_STATUS_INVALID_IE;
goto OnAssocReq23aFail;
}
- if (elems.wps_ie) {
- DBG_8723A("STA included WPS IE in "
- "(Re)Association Request - WPS is "
- "used\n");
+ 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);
+ 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);
-
+ if (copy_len > 0)
+ memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len);
}
/* check if there is WMM IE & support WWM-PS */
pstat->uapsd_vi = 0;
pstat->uapsd_be = 0;
pstat->uapsd_bk = 0;
- if (pmlmepriv->qospriv.qos_option)
- {
- p = pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset; ie_len = 0;
- for (;;)
- {
- p = rtw_get_ie23a(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - sizeof(struct ieee80211_hdr_3addr) - ie_offset);
- if (p != NULL) {
- if (!memcmp(p+2, WMM_IE, 6)) {
-
+ if (pmlmepriv->qospriv.qos_option) {
+ const u8 *end = pos + left;
+ p = pos;
+
+ for (;;) {
+ left = end - p;
+ p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p, left);
+ if (p) {
+ if (!memcmp(p + 2, WMM_IE, 6)) {
pstat->flags |= WLAN_STA_WME;
pstat->qos_option = 1;
- pstat->qos_info = *(p+8);
+ pstat->qos_info = *(p + 8);
- pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
+ pstat->max_sp_len =
+ (pstat->qos_info >> 5) & 0x3;
- if ((pstat->qos_info&0xf) != 0xf)
+ 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))
+ 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))
+ if (pstat->qos_info & BIT(1))
pstat->uapsd_vi = BIT(0)|BIT(1);
else
pstat->uapsd_vi = 0;
- if (pstat->qos_info&BIT(2))
+ if (pstat->qos_info & BIT(2))
pstat->uapsd_bk = BIT(0)|BIT(1);
else
pstat->uapsd_bk = 0;
- if (pstat->qos_info&BIT(3))
+ if (pstat->qos_info & BIT(3))
pstat->uapsd_be = BIT(0)|BIT(1);
else
pstat->uapsd_be = 0;
break;
}
- }
- else {
+ } else {
break;
}
- p = p + ie_len + 2;
+ p = p + p[1] + 2;
}
}
/* save HT capabilities in the sta object */
memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
- if (elems.ht_capabilities && elems.ht_capabilities_len >= 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, elems.ht_capabilities, sizeof(struct ieee80211_ht_cap));
-
+ memcpy(&pstat->htpriv.ht_cap, p + 2,
+ sizeof(struct ieee80211_ht_cap));
} else
pstat->flags &= ~WLAN_STA_HT;
- if ((pmlmepriv->htpriv.ht_option == false) && (pstat->flags&WLAN_STA_HT))
- {
+ if (pmlmepriv->htpriv.ht_option == false && 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: " MAC_FMT " tried to "
- "use TKIP with HT association\n", MAC_ARG(pstat->hwaddr));
+ if (pstat->flags & WLAN_STA_HT &&
+ (pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP ||
+ pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
+ DBG_8723A("HT: " MAC_FMT " tried to use TKIP with HT "
+ "association\n", MAC_ARG(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) {
if (status != WLAN_STATUS_SUCCESS)
goto OnAssocReq23aFail;
-#ifdef CONFIG_8723AU_P2P
- pstat->is_p2p_device = false;
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- {
- if ((p2pie = rtw_get_p2p_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset, pkt_len - sizeof(struct ieee80211_hdr_3addr) - ie_offset, NULL, &p2pielen)))
- {
- pstat->is_p2p_device = true;
- if ((p2p_status_code = (u8)process_assoc_req_p2p_ie23a(pwdinfo, pframe, pkt_len, pstat))>0)
- {
- pstat->p2p_status_code = p2p_status_code;
- status = WLAN_STATUS_CAPS_UNSUPPORTED;
- goto OnAssocReq23aFail;
- }
- }
-#ifdef CONFIG_8723AU_P2P
- if (rtw_get_wfd_ie(pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset, pkt_len - sizeof(struct ieee80211_hdr_3addr) - ie_offset, wfd_ie, &wfd_ielen))
- {
- u8 attr_content[ 10 ] = { 0x00 };
- u32 attr_contentlen = 0;
-
- DBG_8723A("[%s] WFD IE Found!!\n", __func__);
- rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
- if (attr_contentlen)
- {
- pwdinfo->wfd_info->peer_rtsp_ctrlport = get_unaligned_be16(attr_content + 2);
- DBG_8723A("[%s] Peer PORT NUM = %d\n", __func__, pwdinfo->wfd_info->peer_rtsp_ctrlport);
- }
- }
-#endif
- }
- pstat->p2p_status_code = p2p_status_code;
-#endif /* CONFIG_8723AU_P2P */
-
/* TODO: identify_proprietary_vendor_ie(); */
/* Realtek proprietary IE */
/* identify if this is Broadcom sta */
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_STATE;
pstat->state |= WIFI_FW_ASSOC_SUCCESS;
spin_lock_bh(&pstapriv->auth_list_lock);
spin_unlock_bh(&pstapriv->asoc_list_lock);
/* now the station is qualified to join our BSS... */
- if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) &&
- (WLAN_STATUS_SUCCESS == status)) {
+ if (pstat && pstat->state & WIFI_FW_ASSOC_SUCCESS &&
+ status == WLAN_STATUS_SUCCESS) {
#ifdef CONFIG_8723AU_AP_MODE
/* 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(frame_control))
- issue_asocrsp23a(padapter, status, pstat, WIFI_ASSOCRSP);
+ if (ieee80211_is_assoc_req(mgmt->frame_control))
+ issue_asocrsp23a(padapter, status, pstat,
+ WIFI_ASSOCRSP);
else
- issue_asocrsp23a(padapter, status, pstat, WIFI_REASSOCRSP);
+ issue_asocrsp23a(padapter, status, pstat,
+ WIFI_REASSOCRSP);
/* 2 - report to upper layer */
DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
asoc_class2_error:
#ifdef CONFIG_8723AU_AP_MODE
- issue_deauth23a(padapter, hdr->addr2, status);
+ issue_deauth23a(padapter, mgmt->sa, status);
#endif
-
return _FAIL;
OnAssocReq23aFail:
#ifdef CONFIG_8723AU_AP_MODE
pstat->aid = 0;
- if (ieee80211_is_assoc_req(frame_control))
+ if (ieee80211_is_assoc_req(mgmt->frame_control))
issue_asocrsp23a(padapter, status, pstat, WIFI_ASSOCRSP);
else
issue_asocrsp23a(padapter, status, pstat, WIFI_REASSOCRSP);
return _FAIL;
}
-unsigned int OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
+static int
+OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
- uint i;
- int res;
- unsigned short status;
struct ndis_802_11_var_ies *pIE;
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_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_mgmt *pmgmt = (struct ieee80211_mgmt *) skb->data;
+ int res, i;
+ unsigned short status;
u8 *pframe = skb->data;
- uint pkt_len = skb->len;
+ int pkt_len = skb->len;
DBG_8723A("%s\n", __func__);
/* check A1 matches or not */
- if (!ether_addr_equal(myid(&padapter->eeprompriv),
- ieee80211_get_DA(hdr)))
+ if (!ether_addr_equal(myid(&padapter->eeprompriv), pmgmt->da))
return _SUCCESS;
if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
del_timer_sync(&pmlmeext->link_timer);
/* status */
- if ((status = le16_to_cpu(*(unsigned short *)(pframe + sizeof(struct ieee80211_hdr_3addr) + 2))) > 0)
- {
+ status = le16_to_cpu(pmgmt->u.assoc_resp.status_code);
+ if (status > 0) {
DBG_8723A("assoc reject, status code: %d\n", status);
pmlmeinfo->state = WIFI_FW_NULL_STATE;
res = -4;
}
/* get capabilities */
- pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + sizeof(struct ieee80211_hdr_3addr)));
+ 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 = (int)(le16_to_cpu(*(unsigned short *)(pframe + sizeof(struct ieee80211_hdr_3addr) + 4))&0x3fff);
+ res = pmlmeinfo->aid = le16_to_cpu(pmgmt->u.assoc_resp.aid) & 0x3fff;
/* following are moved to join event callback function */
/* to handle HT, WMM, rate adaptive, update MAC reg */
/* for not to handle the synchronous IO in the tasklet */
- for (i = (6 + sizeof(struct ieee80211_hdr_3addr)); i < pkt_len;) {
+ for (i = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
+ i < pkt_len;) {
pIE = (struct ndis_802_11_var_ies *)(pframe + i);
switch (pIE->ElementID)
{
- case _VENDOR_SPECIFIC_IE_:
+ case WLAN_EID_VENDOR_SPECIFIC:
if (!memcmp(pIE->data, WMM_PARA_OUI23A, 6))/* WMM */
- WMM_param_handler23a(padapter, pIE);
-#if defined(CONFIG_8723AU_P2P)
- else if (!memcmp(pIE->data, WFD_OUI23A, 4)) { /* WFD */
- DBG_8723A("[%s] Found WFD IE\n", __func__);
- WFD_info_handler(padapter, pIE);
- }
-#endif
+ WMM_param_handler23a(padapter, pIE);
break;
- case _HT_CAPABILITY_IE_: /* HT caps */
+ case WLAN_EID_HT_CAPABILITY: /* HT caps */
HT_caps_handler23a(padapter, pIE);
break;
- case _HT_EXTRA_INFO_IE_: /* HT info */
+ case WLAN_EID_HT_OPERATION: /* HT info */
HT_info_handler23a(padapter, pIE);
break;
- case _ERPINFO_IE_:
+ case WLAN_EID_ERP_INFO:
ERP_IE_handler23a(padapter, pIE);
default:
i += (pIE->Length + 2);
}
- pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
+ pmlmeinfo->state &= ~WIFI_FW_ASSOC_STATE;
pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
/* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
return _SUCCESS;
}
-unsigned int OnDeAuth23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
+static int
+OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
- unsigned short reason;
+ unsigned short reason;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u8 *pframe = skb->data;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif /* CONFIG_8723AU_P2P */
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- /* check A3 */
- if (!ether_addr_equal(hdr->addr3, get_my_bssid23a(&pmlmeinfo->network)))
+ if (!ether_addr_equal(mgmt->bssid,
+ get_my_bssid23a(&pmlmeinfo->network)))
return _SUCCESS;
-#ifdef CONFIG_8723AU_P2P
- if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
- mod_timer(&pwdinfo->reset_ch_sitesurvey,
- jiffies + msecs_to_jiffies(10));
- }
-#endif /* CONFIG_8723AU_P2P */
-
- reason = le16_to_cpu(*(unsigned short *)(pframe + sizeof(struct ieee80211_hdr_3addr)));
+ reason = le16_to_cpu(mgmt->u.deauth.reason_code);
DBG_8723A("%s Reason code(%d)\n", __func__, reason);
struct sta_priv *pstapriv = &padapter->stapriv;
DBG_8723A_LEVEL(_drv_always_, "ap recv deauth reason code(%d) "
- "sta:%pM\n", reason, hdr->addr2);
+ "sta:%pM\n", reason, mgmt->sa);
- psta = rtw_get_stainfo23a(pstapriv, hdr->addr2);
+ psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
if (psta) {
u8 updated = 0;
}
return _SUCCESS;
- }
- else
+ } else
#endif
{
DBG_8723A_LEVEL(_drv_always_, "sta recv deauth reason code(%d) "
- "sta:%pM\n", reason, hdr->addr3);
+ "sta:%pM\n", reason, mgmt->bssid);
- receive_disconnect23a(padapter, hdr->addr3, reason);
+ receive_disconnect23a(padapter, mgmt->bssid, reason);
}
pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
+
return _SUCCESS;
}
-unsigned int OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
+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_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u8 *pframe = skb->data;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif /* CONFIG_8723AU_P2P */
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- /* check A3 */
- if (!ether_addr_equal(hdr->addr3, get_my_bssid23a(&pmlmeinfo->network)))
+ if (!ether_addr_equal(mgmt->bssid,
+ get_my_bssid23a(&pmlmeinfo->network)))
return _SUCCESS;
-#ifdef CONFIG_8723AU_P2P
- if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
- {
- mod_timer(&pwdinfo->reset_ch_sitesurvey,
- jiffies + msecs_to_jiffies(10));
- }
-#endif /* CONFIG_8723AU_P2P */
-
- reason = le16_to_cpu(*(unsigned short *)
- (pframe + sizeof(struct ieee80211_hdr_3addr)));
+ reason = le16_to_cpu(mgmt->u.disassoc.reason_code);
DBG_8723A("%s Reason code(%d)\n", __func__, reason);
struct sta_priv *pstapriv = &padapter->stapriv;
DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d)"
- " sta:%pM\n", reason, hdr->addr2);
+ " sta:%pM\n", reason, mgmt->sa);
- psta = rtw_get_stainfo23a(pstapriv, hdr->addr2);
+ psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
if (psta) {
u8 updated = 0;
list_del_init(&psta->asoc_list);
pstapriv->asoc_list_cnt--;
updated = ap_free_sta23a(padapter, psta,
- false, reason);
+ false, reason);
}
spin_unlock_bh(&pstapriv->asoc_list_lock);
}
return _SUCCESS;
- }
- else
+ } else
#endif
{
DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason "
- "code(%d) sta:%pM\n", reason, hdr->addr3);
+ "code(%d) sta:%pM\n", reason, mgmt->bssid);
- receive_disconnect23a(padapter, hdr->addr3, reason);
+ receive_disconnect23a(padapter, mgmt->bssid, reason);
}
pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
return _SUCCESS;
}
-unsigned int OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
+static int
+OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
DBG_8723A("%s\n", __func__);
return _SUCCESS;
}
-unsigned int on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
+static int
+on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
return _FAIL;
}
-unsigned int OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
+static int
+OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
return _SUCCESS;
}
-unsigned int OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
+static int
+OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
return _SUCCESS;
}
-unsigned int OnAction23a_back23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
+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 *frame_body;
- unsigned char category, action;
- unsigned short tid, status, reason_code = 0;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ 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_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u8 *pframe = skb->data;
+ 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), hdr->addr1))
+ if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
return _SUCCESS;
DBG_8723A("%s\n", __func__);
if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
return _SUCCESS;
- addr = hdr->addr2;
+ addr = mgmt->sa;
psta = rtw_get_stainfo23a(pstapriv, addr);
if (!psta)
return _SUCCESS;
- frame_body = (unsigned char *)
- (pframe + sizeof(struct ieee80211_hdr_3addr));
-
- category = frame_body[0];
+ category = mgmt->u.action.category;
if (category == WLAN_CATEGORY_BACK) { /* representing Block Ack */
if (!pmlmeinfo->HT_enable)
return _SUCCESS;
- action = frame_body[1];
+ /* 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, &frame_body[2],
+ 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);
}
break;
case WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
- status = get_unaligned_le16(&frame_body[3]);
- tid = ((frame_body[5] >> 2) & 0x7);
+ 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 |= 1 << tid;
break;
case WLAN_ACTION_DELBA: /* DELBA */
- if ((frame_body[3] & BIT(3)) == 0) {
- psta->htpriv.agg_enable_bitmap &=
- ~(1 << ((frame_body[3] >> 4) & 0xf));
- psta->htpriv.candidate_tid_bitmap &=
- ~(1 << ((frame_body[3] >> 4) & 0xf));
-
- /* reason_code = frame_body[4] | (frame_body[5] << 8); */
- reason_code = get_unaligned_le16(&frame_body[4]);
- } else if ((frame_body[3] & BIT(3)) == BIT(3)) {
- tid = (frame_body[3] >> 4) & 0x0F;
+ params = get_unaligned_le16(
+ &mgmt->u.action.u.delba.params);
+ tid = params >> 12;
- preorder_ctrl = &psta->recvreorder_ctrl[tid];
+ 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 &= ~(1 << tid);
+ psta->htpriv.candidate_tid_bitmap &=
+ ~(1 << tid);
}
-
+ reason_code = get_unaligned_le16(
+ &mgmt->u.action.u.delba.reason_code);
DBG_8723A("%s(): DELBA: %x(%x)\n", __func__,
pmlmeinfo->agg_enable_bitmap, reason_code);
/* todo: how to notify the host while receiving
return _SUCCESS;
}
-#ifdef CONFIG_8723AU_P2P
-
-static int get_reg_classes_full_count(struct p2p_channels channel_list) {
- int cnt = 0;
- int i;
-
- for (i = 0; i < channel_list.reg_classes; i++)
- cnt += channel_list.reg_class[i].channels;
-
- return cnt;
-}
-
-void issue_p2p_GO_request23a(struct rtw_adapter *padapter, u8* raddr)
+static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token)
{
- unsigned char category = WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- u32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_GO_NEGO_REQ;
- u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
- u8 wpsielen = 0, p2pielen = 0;
- u16 len_channellist_attr = 0;
-#ifdef CONFIG_8723AU_P2P
- u32 wfdielen = 0;
-#endif /* CONFIG_8723AU_P2P */
-
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- return;
-
- DBG_8723A("[%s] In\n", __func__);
- /* 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;
-
- fctrl = &pwlanhdr->frame_control;
- *fctrl = 0;
-
- ether_addr_copy(pwlanhdr->addr1, raddr);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *)&p2poui,
- &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
- pwdinfo->negotiation_dialog_token = 1; /*Initialize the dialog value*/
- pframe = rtw_set_fixed_ie23a(pframe, 1,
- &pwdinfo->negotiation_dialog_token,
- &pattrib->pktlen);
-
- /* WPS Section */
- wpsielen = 0;
- /* WPS OUI */
- *(u32*) (wpsie) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* WPS version */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
-
- /* Device Password ID */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
-
- if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN)
- {
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
- }
- else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN)
- {
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
- }
- else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC)
- {
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
- }
-
- wpsielen += 2;
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
-
- /* P2P IE Section. */
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20110306 */
- /* According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */
- /* 1. P2P Capability */
- /* 2. Group Owner Intent */
- /* 3. Configuration Timeout */
- /* 4. Listen Channel */
- /* 5. Extended Listen Timing */
- /* 6. Intended P2P Interface Address */
- /* 7. Channel List */
- /* 8. P2P Device Info */
- /* 9. Operating Channel */
-
- /* P2P Capability */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported)
- {
- p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
- }
- else
- {
- p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
- }
-
- /* Group Owner Intent */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0001);
- p2pielen += 2;
-
- /* Value: */
- /* Todo the tie breaker bit. */
- p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
-
- /* Configuration Timeout */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
- p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
-
- /* Listen Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
-
- /* Channel Number */
- p2pie[p2pielen++] = pwdinfo->listen_channel; /* listening channel number */
-
- /* Extended Listen Timing ATTR */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0004);
- p2pielen += 2;
-
- /* Value: */
- /* Availability Period */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF);
- p2pielen += 2;
-
- /* Availability Interval */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF);
- p2pielen += 2;
-
- /* Intended P2P Interface Address */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Channel List */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
- /* Length: */
- /* Country String(3) */
- /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
- /* + number of channels in all classes */
- len_channellist_attr = 3
- + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
- + get_reg_classes_full_count(pmlmeext->channel_list);
-
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Channel Entry List */
-
- {
- int i, j;
- for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
- /* Operating Class */
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
+ struct rtw_adapter *adapter = recv_frame->adapter;
+ struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
+ struct sk_buff *skb = recv_frame->pkt;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ u16 seq_ctrl;
- /* Number of Channels */
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
+ seq_ctrl = ((recv_frame->attrib.seq_num&0xffff) << 4) |
+ (recv_frame->attrib.frag_num & 0xf);
- /* Channel List */
- for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
+ if (ieee80211_has_retry(hdr->frame_control)) {
+ if (token >= 0) {
+ if ((seq_ctrl == mlmeext->action_public_rxseq) &&
+ (token == mlmeext->action_public_dialog_token)) {
+ DBG_8723A(FUNC_ADPT_FMT" seq_ctrl = 0x%x, "
+ "rxseq = 0x%x, token:%d\n",
+ FUNC_ADPT_ARG(adapter), seq_ctrl,
+ mlmeext->action_public_rxseq, token);
+ return _FAIL;
+ }
+ } else {
+ if (seq_ctrl == mlmeext->action_public_rxseq) {
+ DBG_8723A(FUNC_ADPT_FMT" seq_ctrl = 0x%x, "
+ "rxseq = 0x%x\n",
+ FUNC_ADPT_ARG(adapter), seq_ctrl,
+ mlmeext->action_public_rxseq);
+ return _FAIL;
}
}
}
- /* Device Info */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
- /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
+ mlmeext->action_public_rxseq = seq_ctrl;
- /* Config Method */
- /* This field should be big endian. Noted by P2P specification. */
+ if (token >= 0)
+ mlmeext->action_public_dialog_token = token;
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
+ return _SUCCESS;
+}
- p2pielen += 2;
+static unsigned int on_action_public23a_p2p(struct recv_frame *precv_frame)
+{
+ struct sk_buff *skb = precv_frame->pkt;
+ u8 *pframe = skb->data;
+ u8 *frame_body;
+ u8 dialogToken = 0;
- /* Primary Device Type */
- /* Category ID */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
- p2pielen += 2;
+ frame_body = (unsigned char *)
+ (pframe + sizeof(struct ieee80211_hdr_3addr));
- /* OUI */
- *(u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI);
- p2pielen += 4;
+ dialogToken = frame_body[7];
- /* Sub Category ID */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
- p2pielen += 2;
+ if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
+ return _FAIL;
- /* Number of Secondary Device Types */
- p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
+ return _SUCCESS;
+}
- /* Device Name */
- /* Type: */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- p2pielen += 2;
+static unsigned int on_action_public23a_vendor(struct recv_frame *precv_frame)
+{
+ unsigned int ret = _FAIL;
+ struct sk_buff *skb = precv_frame->pkt;
+ u8 *pframe = skb->data;
+ u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
- p2pielen += 2;
+ if (!memcmp(frame_body + 2, P2P_OUI23A, 4)) {
+ ret = on_action_public23a_p2p(precv_frame);
+ }
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_name,
- pwdinfo->device_name_len);
- p2pielen += pwdinfo->device_name_len;
+ return ret;
+}
- /* Operating Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
+static unsigned int
+on_action_public23a_default(struct recv_frame *precv_frame, u8 action)
+{
+ unsigned int ret = _FAIL;
+ struct sk_buff *skb = precv_frame->pkt;
+ u8 *pframe = skb->data;
+ uint frame_len = skb->len;
+ u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
+ u8 token;
+ struct rtw_adapter *adapter = precv_frame->adapter;
+ int cnt = 0;
+ char msg[64];
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
+ token = frame_body[2];
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
+ if (rtw_action_public_decache(precv_frame, token) == _FAIL)
+ goto exit;
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
+ cnt += sprintf((msg+cnt), "%s(token:%u)",
+ action_public_str23a(action), token);
+ rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
- /* Operating Class */
- if (pwdinfo->operating_channel <= 14)
- {
- /* Operating Class */
- p2pie[p2pielen++] = 0x51;
- }
- else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48))
- {
- /* Operating Class */
- p2pie[p2pielen++] = 0x73;
- }
- else
- {
- /* Operating Class */
- p2pie[p2pielen++] = 0x7c;
- }
+ ret = _SUCCESS;
- /* Channel Number */
- p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
+exit:
+ return ret;
+}
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
+static int on_action_public23a(struct rtw_adapter *padapter,
+ struct recv_frame *precv_frame)
+{
+ unsigned int ret = _FAIL;
+ struct sk_buff *skb = precv_frame->pkt;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ u8 *pframe = skb->data;
+ u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
+ u8 category, action;
-#ifdef CONFIG_8723AU_P2P
- wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
-#endif /* CONFIG_8723AU_P2P */
+ /* check RA matches or not */
+ if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
+ goto exit;
- pattrib->last_txcmdsz = pattrib->pktlen;
+ category = frame_body[0];
+ if (category != WLAN_CATEGORY_PUBLIC)
+ goto exit;
- dump_mgntframe23a(padapter, pmgntframe);
+ action = frame_body[1];
+ switch (action) {
+ case ACT_PUBLIC_VENDOR:
+ ret = on_action_public23a_vendor(precv_frame);
+ break;
+ default:
+ ret = on_action_public23a_default(precv_frame, action);
+ break;
+ }
- return;
+exit:
+ return ret;
}
-static void issue_p2p_GO_response(struct rtw_adapter *padapter, u8* raddr, u8* frame_body, uint len, u8 result)
-{
-
- unsigned char category = WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- u32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_GO_NEGO_RESP;
- u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
- u8 p2pielen = 0;
- uint wpsielen = 0;
- u16 wps_devicepassword_id = 0x0000;
- uint wps_devicepassword_id_len = 0;
- u16 len_channellist_attr = 0;
- int i, j;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#ifdef CONFIG_8723AU_P2P
- u32 wfdielen = 0;
-#endif /* CONFIG_8723AU_P2P */
-
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- return;
-
- DBG_8723A("[%s] In, result = %d\n", __func__, result);
- /* 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;
-
- fctrl = &pwlanhdr->frame_control;
- *fctrl = 0;
-
- ether_addr_copy(pwlanhdr->addr1, raddr);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *) &p2poui,
- &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
- /* The Dialog Token of provisioning discovery request frame. */
- pwdinfo->negotiation_dialog_token = frame_body[7];
- pframe = rtw_set_fixed_ie23a(pframe, 1,
- &pwdinfo->negotiation_dialog_token,
- &pattrib->pktlen);
-
- /* Commented by Albert 20110328 */
- /* Try to get the device password ID from the WPS IE of group
- negotiation request frame */
- /* WiFi Direct test plan 5.1.15 */
- rtw_get_wps_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_,
- len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
- rtw_get_wps_attr_content23a(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID,
- (u8 *)&wps_devicepassword_id,
- &wps_devicepassword_id_len);
- wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
-
- memset(wpsie, 0x00, 255);
- wpsielen = 0;
-
- /* WPS Section */
- wpsielen = 0;
- /* WPS OUI */
- *(u32*) (wpsie) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* WPS version */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
-
- /* Device Password ID */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
- if (wps_devicepassword_id == WPS_DPID_USER_SPEC) {
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
- } else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) {
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
- } else {
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
- }
- wpsielen += 2;
-
- /* Commented by Kurt 20120113 */
- /* If some device wants to do p2p handshake without sending prov_disc_req */
- /* We have to get peer_req_cm from here. */
- if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) {
- if (wps_devicepassword_id == WPS_DPID_USER_SPEC) {
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
- } else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) {
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
- } else {
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
- }
- }
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen,
- (unsigned char *) wpsie, &pattrib->pktlen);
-
- /* P2P IE Section. */
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20100908 */
- /* According to the P2P Specification, the group negoitation
- response frame should contain 9 P2P attributes */
- /* 1. Status */
- /* 2. P2P Capability */
- /* 3. Group Owner Intent */
- /* 4. Configuration Timeout */
- /* 5. Operating Channel */
- /* 6. Intended P2P Interface Address */
- /* 7. Channel List */
- /* 8. Device Info */
- /* 9. Group ID (Only GO) */
-
- /* ToDo: */
-
- /* P2P Status */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_STATUS;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0001);
- p2pielen += 2;
-
- /* Value: */
- p2pie[p2pielen++] = result;
-
- /* P2P Capability */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
- /* Commented by Albert 2011/03/08 */
- /* According to the P2P specification */
- /* if the sending device will be client, the P2P
- Capability should be reserved of group negotation
- response frame */
- p2pie[p2pielen++] = 0;
- } else {
- /* Be group owner or meet the error case */
- p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
- }
-
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported) {
- p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN |
- P2P_GRPCAP_PERSISTENT_GROUP;
- } else {
- p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
- }
-
- /* Group Owner Intent */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0001);
- p2pielen += 2;
-
- /* Value: */
- if (pwdinfo->peer_intent & 0x01) {
- /* Peer's tie breaker bit is 1, our tie breaker
- bit should be 0 */
- p2pie[p2pielen++] = (pwdinfo->intent << 1);
- } else {
- /* Peer's tie breaker bit is 0, our tie breaker bit
- should be 1 */
- p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
- }
-
- /* Configuration Timeout */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* 2 seconds needed to be the P2P GO */
- p2pie[p2pielen++] = 200;
- /* 2 seconds needed to be the P2P Client */
- p2pie[p2pielen++] = 200;
-
- /* Operating Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- if (pwdinfo->operating_channel <= 14) {
- /* Operating Class */
- p2pie[p2pielen++] = 0x51;
- } else if ((pwdinfo->operating_channel >= 36) &&
- (pwdinfo->operating_channel <= 48)) {
- /* Operating Class */
- p2pie[p2pielen++] = 0x73;
- } else {
- /* Operating Class */
- p2pie[p2pielen++] = 0x7c;
- }
-
- /* Channel Number */
- /* operating channel number */
- p2pie[p2pielen++] = pwdinfo->operating_channel;
-
- /* Intended P2P Interface Address */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Channel List */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
- /* Country String(3) */
- /* + (Operating Class (1) + Number of Channels(1)) *
- Operation Classes (?) */
- /* + number of channels in all classes */
- len_channellist_attr = 3 +
- (1 + 1) * (u16)pmlmeext->channel_list.reg_classes +
- get_reg_classes_full_count(pmlmeext->channel_list);
-
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
-
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Channel Entry List */
-
- for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
- /* Operating Class */
- p2pie[p2pielen++] =
- pmlmeext->channel_list.reg_class[j].reg_class;
-
- /* Number of Channels */
- p2pie[p2pielen++] =
- pmlmeext->channel_list.reg_class[j].channels;
-
- /* Channel List */
- for (i = 0;
- i < pmlmeext->channel_list.reg_class[j].channels; i++) {
- p2pie[p2pielen++] =
- pmlmeext->channel_list.reg_class[j].channel[i];
- }
- }
-
- /* Device Info */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) +
- Primary Device Type (8bytes) */
- /* + NumofSecondDevType (1byte) + WPS Device Name ID field
- (2bytes) + WPS Device Name Len field (2bytes) */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Config Method */
- /* This field should be big endian. Noted by P2P specification. */
-
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
-
- p2pielen += 2;
-
- /* Primary Device Type */
- /* Category ID */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
- p2pielen += 2;
-
- /* OUI */
- *(u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI);
- p2pielen += 4;
-
- /* Sub Category ID */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
- p2pielen += 2;
-
- /* Number of Secondary Device Types */
- p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
-
- /* Device Name */
- /* Type: */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- p2pielen += 2;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_name,
- pwdinfo->device_name_len);
- p2pielen += pwdinfo->device_name_len;
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- {
- /* Group ID Attribute */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) =
- cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
- p2pielen += 2;
-
- /* Value: */
- /* p2P Device Address */
- memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* SSID */
- memcpy(p2pie + p2pielen, pwdinfo->nego_ssid,
- pwdinfo->nego_ssidlen);
- p2pielen += pwdinfo->nego_ssidlen;
-
- }
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
- (unsigned char *) p2pie, &pattrib->pktlen);
-
-#ifdef CONFIG_8723AU_P2P
- wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
-#endif /* CONFIG_8723AU_P2P */
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-
- return;
-}
-
-static void issue_p2p_GO_confirm(struct rtw_adapter *padapter, u8* raddr,
- u8 result)
-{
-
- unsigned char category = WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- u32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_GO_NEGO_CONF;
- u8 p2pie[ 255 ] = { 0x00 };
- u8 p2pielen = 0;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#ifdef CONFIG_8723AU_P2P
- u32 wfdielen = 0;
-#endif /* CONFIG_8723AU_P2P */
-
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- return;
-
- DBG_8723A("[%s] In\n", __func__);
- /* 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;
-
- fctrl = &pwlanhdr->frame_control;
- *fctrl = 0;
-
- ether_addr_copy(pwlanhdr->addr1, raddr);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *)&p2poui,
- &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1,
- &pwdinfo->negotiation_dialog_token,
- &pattrib->pktlen);
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20110306 */
- /* According to the P2P Specification, the group negoitation
- request frame should contain 5 P2P attributes */
- /* 1. Status */
- /* 2. P2P Capability */
- /* 3. Operating Channel */
- /* 4. Channel List */
- /* 5. Group ID (if this WiFi is GO) */
-
- /* P2P Status */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_STATUS;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0001);
- p2pielen += 2;
-
- /* Value: */
- p2pie[p2pielen++] = result;
-
- /* P2P Capability */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported) {
- p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN |
- P2P_GRPCAP_PERSISTENT_GROUP;
- } else {
- p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
- }
-
- /* Operating Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
- if (pwdinfo->peer_operating_ch <= 14) {
- /* Operating Class */
- p2pie[p2pielen++] = 0x51;
- } else if ((pwdinfo->peer_operating_ch >= 36) &&
- (pwdinfo->peer_operating_ch <= 48)) {
- /* Operating Class */
- p2pie[p2pielen++] = 0x73;
- } else {
- /* Operating Class */
- p2pie[p2pielen++] = 0x7c;
- }
-
- p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
- } else {
- if (pwdinfo->operating_channel <= 14) {
- /* Operating Class */
- p2pie[p2pielen++] = 0x51;
- }
- else if ((pwdinfo->operating_channel >= 36) &&
- (pwdinfo->operating_channel <= 48)) {
- /* Operating Class */
- p2pie[p2pielen++] = 0x73;
- } else {
- /* Operating Class */
- p2pie[p2pielen++] = 0x7c;
- }
-
- /* Channel Number */
- /* Use the listen channel as the operating channel */
- p2pie[p2pielen++] = pwdinfo->operating_channel;
- }
-
- /* Channel List */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) =
- cpu_to_le16(pwdinfo->channel_list_attr_len);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->channel_list_attr,
- pwdinfo->channel_list_attr_len);
- p2pielen += pwdinfo->channel_list_attr_len;
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- /* Group ID Attribute */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) =
- cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
- p2pielen += 2;
-
- /* Value: */
- /* p2P Device Address */
- memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* SSID */
- memcpy(p2pie + p2pielen, pwdinfo->nego_ssid,
- pwdinfo->nego_ssidlen);
- p2pielen += pwdinfo->nego_ssidlen;
- }
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
- (unsigned char *)p2pie, &pattrib->pktlen);
-
-#ifdef CONFIG_8723AU_P2P
- wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
-#endif /* CONFIG_8723AU_P2P */
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-
- return;
-}
-
-void issue_p2p_invitation_request23a(struct rtw_adapter *padapter, u8* raddr)
-{
- unsigned char category = WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- u32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_INVIT_REQ;
- u8 p2pie[ 255 ] = { 0x00 };
- u8 p2pielen = 0;
- u8 dialogToken = 3;
- u16 len_channellist_attr = 0;
-#ifdef CONFIG_8723AU_P2P
- u32 wfdielen = 0;
-#endif /* CONFIG_8723AU_P2P */
- int i, j;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- 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;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- fctrl = &pwlanhdr->frame_control;
- *fctrl = 0;
-
- ether_addr_copy(pwlanhdr->addr1, raddr);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, raddr);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *) &p2poui,
- &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
-
- /* P2P IE Section. */
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20101011 */
- /* According to the P2P Specification, the P2P Invitation
- request frame should contain 7 P2P attributes */
- /* 1. Configuration Timeout */
- /* 2. Invitation Flags */
- /* 3. Operating Channel (Only GO) */
- /* 4. P2P Group BSSID (Should be included if I am the GO) */
- /* 5. Channel List */
- /* 6. P2P Group ID */
- /* 7. P2P Device Info */
-
- /* Configuration Timeout */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* 2 seconds needed to be the P2P GO */
- p2pie[p2pielen++] = 200;
- /* 2 seconds needed to be the P2P Client */
- p2pie[p2pielen++] = 200;
-
- /* Invitation Flags */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_INVITATION_FLAGS;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0001);
- p2pielen += 2;
-
- /* Value: */
- p2pie[p2pielen++] = P2P_INVITATION_FLAGS_PERSISTENT;
-
- /* Operating Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- if (pwdinfo->invitereq_info.operating_ch <= 14)
- p2pie[p2pielen++] = 0x51;
- else if ((pwdinfo->invitereq_info.operating_ch >= 36) &&
- (pwdinfo->invitereq_info.operating_ch <= 48))
- p2pie[p2pielen++] = 0x73;
- else
- p2pie[p2pielen++] = 0x7c;
-
- /* Channel Number */
- /* operating channel number */
- p2pie[p2pielen++] = pwdinfo->invitereq_info.operating_ch;
-
- if (ether_addr_equal(myid(&padapter->eeprompriv),
- pwdinfo->invitereq_info.go_bssid)) {
- /* P2P Group BSSID */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address for GO */
- memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid,
- ETH_ALEN);
- p2pielen += ETH_ALEN;
- }
-
- /* Channel List */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
- /* Length: */
- /* Country String(3) */
- /* + (Operating Class (1) + Number of Channels(1)) *
- Operation Classes (?) */
- /* + number of channels in all classes */
- len_channellist_attr = 3 +
- (1 + 1) * (u16)pmlmeext->channel_list.reg_classes +
- get_reg_classes_full_count(pmlmeext->channel_list);
-
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Channel Entry List */
- for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
- /* Operating Class */
- p2pie[p2pielen++] =
- pmlmeext->channel_list.reg_class[j].reg_class;
-
- /* Number of Channels */
- p2pie[p2pielen++] =
- pmlmeext->channel_list.reg_class[j].channels;
-
- /* Channel List */
- for (i = 0;
- i < pmlmeext->channel_list.reg_class[j].channels; i++) {
- p2pie[p2pielen++] =
- pmlmeext->channel_list.reg_class[j].channel[i];
- }
- }
-
- /* P2P Group ID */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) =
- cpu_to_le16(6 + pwdinfo->invitereq_info.ssidlen);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address for GO */
- memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* SSID */
- memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid,
- pwdinfo->invitereq_info.ssidlen);
- p2pielen += pwdinfo->invitereq_info.ssidlen;
-
- /* Device Info */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) +
- Primary Device Type (8bytes) */
- /* + NumofSecondDevType (1byte) + WPS Device Name ID field
- (2bytes) + WPS Device Name Len field (2bytes) */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Config Method */
- /* This field should be big endian. Noted by P2P specification. */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
- p2pielen += 2;
-
- /* Primary Device Type */
- /* Category ID */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
- p2pielen += 2;
-
- /* OUI */
- *(u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI);
- p2pielen += 4;
-
- /* Sub Category ID */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
- p2pielen += 2;
-
- /* Number of Secondary Device Types */
- p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
-
- /* Device Name */
- /* Type: */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- p2pielen += 2;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_name,
- pwdinfo->device_name_len);
- p2pielen += pwdinfo->device_name_len;
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
- (unsigned char *) p2pie, &pattrib->pktlen);
-
-#ifdef CONFIG_8723AU_P2P
- wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
-#endif /* CONFIG_8723AU_P2P */
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-
- return;
-}
-
-void issue_p2p_invitation_response23a(struct rtw_adapter *padapter, u8 *raddr,
- u8 dialogToken, u8 status_code)
-{
- unsigned char category = WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- u32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_INVIT_RESP;
- u8 p2pie[ 255 ] = { 0x00 };
- u8 p2pielen = 0;
- u16 len_channellist_attr = 0;
-#ifdef CONFIG_8723AU_P2P
- u32 wfdielen = 0;
-#endif /* CONFIG_8723AU_P2P */
- int i, j;
-
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- 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;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- fctrl = &pwlanhdr->frame_control;
- *fctrl = 0;
-
- ether_addr_copy(pwlanhdr->addr1, raddr);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, raddr);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *)&p2poui,
- &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
-
- /* P2P IE Section. */
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20101005 */
- /* According to the P2P Specification, the P2P Invitation
- response frame should contain 5 P2P attributes */
- /* 1. Status */
- /* 2. Configuration Timeout */
- /* 3. Operating Channel (Only GO) */
- /* 4. P2P Group BSSID (Only GO) */
- /* 5. Channel List */
-
- /* P2P Status */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_STATUS;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0001);
- p2pielen += 2;
-
- /* Value: */
- /* When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */
- /* Sent the event receiving the P2P Invitation Req frame
- to DMP UI. */
- /* DMP had to compare the MAC address to find out the profile. */
- /* So, the WiFi driver will send the
- P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */
- /* If the UI found the corresponding profile, the WiFi driver
- sends the P2P Invitation Req */
- /* to NB to rebuild the persistent group. */
- p2pie[p2pielen++] = status_code;
-
- /* Configuration Timeout */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* 2 seconds needed to be the P2P GO */
- p2pie[p2pielen++] = 200;
- /* 2 seconds needed to be the P2P Client */
- p2pie[p2pielen++] = 200;
-
- if (status_code == P2P_STATUS_SUCCESS) {
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- /* The P2P Invitation request frame asks this
- Wi-Fi device to be the P2P GO */
- /* In this case, the P2P Invitation response
- frame should carry the two more P2P attributes. */
- /* First one is operating channel attribute. */
- /* Second one is P2P Group BSSID attribute. */
-
- /* Operating Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute"
- section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- /* Copy from SD7 */
- p2pie[p2pielen++] = 0x51;
-
- /* Channel Number */
- /* operating channel number */
- p2pie[p2pielen++] = pwdinfo->operating_channel;
-
- /* P2P Group BSSID */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address for GO */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv),
- ETH_ALEN);
- p2pielen += ETH_ALEN;
- }
-
- /* Channel List */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
- /* Length: */
- /* Country String(3) */
- /* + (Operating Class (1) + Number of Channels(1)) *
- Operation Classes (?) */
- /* + number of channels in all classes */
- len_channellist_attr = 3 +
- (1 + 1) * (u16)pmlmeext->channel_list.reg_classes +
- get_reg_classes_full_count(pmlmeext->channel_list);
-
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Channel Entry List */
- for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
- /* Operating Class */
- p2pie[p2pielen++] =
- pmlmeext->channel_list.reg_class[j].reg_class;
-
- /* Number of Channels */
- p2pie[p2pielen++] =
- pmlmeext->channel_list.reg_class[j].channels;
-
- /* Channel List */
- for (i = 0;
- i < pmlmeext->channel_list.reg_class[j].channels;
- i++) {
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
- }
- }
- }
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
- (unsigned char *)p2pie, &pattrib->pktlen);
-
-#ifdef CONFIG_8723AU_P2P
- wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
-#endif /* CONFIG_8723AU_P2P */
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-
- return;
-}
-
-void issue_p2p_provision_request23a(struct rtw_adapter *padapter, u8 *pssid,
- u8 ussidlen, u8 *pdev_raddr)
-{
- unsigned char category = WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- u8 dialogToken = 1;
- u32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_PROVISION_DISC_REQ;
- u8 wpsie[100] = { 0x00 };
- u8 wpsielen = 0;
- u32 p2pielen = 0;
-#ifdef CONFIG_8723AU_P2P
- u32 wfdielen = 0;
-#endif /* CONFIG_8723AU_P2P */
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- return;
-
- DBG_8723A("[%s] In\n", __func__);
- /* 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;
-
- fctrl = &pwlanhdr->frame_control;
- *fctrl = 0;
-
- ether_addr_copy(pwlanhdr->addr1, pdev_raddr);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, pdev_raddr);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *)&p2poui,
- &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
-
- p2pielen = build_prov_disc_request_p2p_ie23a(pwdinfo, pframe, pssid,
- ussidlen, pdev_raddr);
-
- pframe += p2pielen;
- pattrib->pktlen += p2pielen;
-
- wpsielen = 0;
- /* WPS OUI */
- *(u32*) (wpsie) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* WPS version */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
-
- /* Config Method */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
- wpsielen += 2;
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen,
- (unsigned char *) wpsie, &pattrib->pktlen);
-
-#ifdef CONFIG_8723AU_P2P
- wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
-#endif /* CONFIG_8723AU_P2P */
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-
- return;
-}
-
-static u8 is_matched_in_profilelist(u8 *peermacaddr,
- struct profile_info *profileinfo)
-{
- u8 i, match_result = 0;
-
- DBG_8723A("[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __func__,
- peermacaddr[0], peermacaddr[1], peermacaddr[2],
- peermacaddr[3], peermacaddr[4], peermacaddr[5]);
-
- for (i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++) {
- DBG_8723A("[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X "
- "%.2X\n", __func__, profileinfo->peermac[0],
- profileinfo->peermac[1], profileinfo->peermac[2],
- profileinfo->peermac[3], profileinfo->peermac[4],
- profileinfo->peermac[5]);
- if (ether_addr_equal(peermacaddr, profileinfo->peermac)) {
- match_result = 1;
- DBG_8723A("[%s] Match!\n", __func__);
- break;
- }
- }
-
- return match_result;
-}
-
-void issue_probersp23a_p2p23a(struct rtw_adapter *padapter, unsigned char *da)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- unsigned char *mac;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- u16 beacon_interval = 100;
- u16 capInfo = 0;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 wpsie[255] = { 0x00 };
- u32 wpsielen = 0, p2pielen = 0;
-#ifdef CONFIG_8723AU_P2P
- u32 wfdielen = 0;
-#endif /* CONFIG_8723AU_P2P */
- struct cfg80211_wifidirect_info *pcfg80211_wdinfo =
- &padapter->cfg80211_wdinfo;
- struct ieee80211_channel *ieee_ch =
- &pcfg80211_wdinfo->remain_on_ch_channel;
- u8 listen_channel =
- (u8)ieee80211_frequency_to_channel(ieee_ch->center_freq);
-
- /* DBG_8723A("%s\n", __func__); */
-
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- {
- 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;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- mac = myid(&padapter->eeprompriv);
-
- fctrl = &pwlanhdr->frame_control;
- *fctrl = 0;
- ether_addr_copy(pwlanhdr->addr1, da);
- ether_addr_copy(pwlanhdr->addr2, mac);
-
- /* Use the device address for BSSID field. */
- ether_addr_copy(pwlanhdr->addr3, mac);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(fctrl, WIFI_PROBERSP);
-
- pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = pattrib->hdrlen;
- pframe += pattrib->hdrlen;
-
- /* timestamp will be inserted by hardware */
- pframe += 8;
- pattrib->pktlen += 8;
-
- /* beacon interval: 2 bytes */
- memcpy(pframe, (unsigned char *) &beacon_interval, 2);
- pframe += 2;
- pattrib->pktlen += 2;
-
- /* capability info: 2 bytes */
- /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of
- WiFi Direct Spec) */
- capInfo |= cap_ShortPremble;
- capInfo |= cap_ShortSlot;
-
- memcpy(pframe, (unsigned char *) &capInfo, 2);
- pframe += 2;
- pattrib->pktlen += 2;
-
- /* SSID */
- pframe = rtw_set_ie23a(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid,
- &pattrib->pktlen);
-
- /* supported rates... */
- /* Use the OFDM rate in the P2P probe response frame.
- (6(B), 9(B), 12, 18, 24, 36, 48, 54) */
- pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_, 8,
- pwdinfo->support_rate, &pattrib->pktlen);
-
- /* DS parameter set */
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled &&
- listen_channel != 0) {
- pframe = rtw_set_ie23a(pframe, _DSSET_IE_, 1, (unsigned char *)
- &listen_channel, &pattrib->pktlen);
- } else {
- pframe = rtw_set_ie23a(pframe, _DSSET_IE_, 1, (unsigned char *)
- &pwdinfo->listen_channel,
- &pattrib->pktlen);
- }
-
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
- if (pmlmepriv->wps_probe_resp_ie &&
- pmlmepriv->p2p_probe_resp_ie) {
- /* WPS IE */
- memcpy(pframe, pmlmepriv->wps_probe_resp_ie,
- pmlmepriv->wps_probe_resp_ie_len);
- pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
- pframe += pmlmepriv->wps_probe_resp_ie_len;
-
- /* P2P IE */
- memcpy(pframe, pmlmepriv->p2p_probe_resp_ie,
- pmlmepriv->p2p_probe_resp_ie_len);
- pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
- pframe += pmlmepriv->p2p_probe_resp_ie_len;
- }
- } else {
-
- /* Todo: WPS IE */
- /* Noted by Albert 20100907 */
- /* According to the WPS specification, all the WPS
- attribute is presented by Big Endian. */
-
- wpsielen = 0;
- /* WPS OUI */
- *(u32*) (wpsie) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* WPS version */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
-
- /* WiFi Simple Config State */
- /* Type: */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;
-
- /* Response Type */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
-
- /* UUID-E */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0010);
- wpsielen += 2;
-
- /* Value: */
- memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv), ETH_ALEN);
- wpsielen += 0x10;
-
- /* Manufacturer */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0007);
- wpsielen += 2;
-
- /* Value: */
- memcpy(wpsie + wpsielen, "Realtek", 7);
- wpsielen += 7;
-
- /* Model Name */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0006);
- wpsielen += 2;
-
- /* Value: */
- memcpy(wpsie + wpsielen, "8192CU", 6);
- wpsielen += 6;
-
- /* Model Number */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[ wpsielen++ ] = 0x31; /* character 1 */
-
- /* Serial Number */
- /* Type: */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
- wpsielen += 2;
-
- /* Value: */
- memcpy(wpsie + wpsielen, "123456", ETH_ALEN);
- wpsielen += ETH_ALEN;
-
- /* Primary Device Type */
- /* Type: */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0008);
- wpsielen += 2;
-
- /* Value: */
- /* Category ID */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
- wpsielen += 2;
-
- /* OUI */
- *(u32*) (wpsie + wpsielen) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* Sub Category ID */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
- wpsielen += 2;
-
- /* Device Name */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(pwdinfo->device_name_len);
- wpsielen += 2;
-
- /* Value: */
- if (pwdinfo->device_name_len) {
- memcpy(wpsie + wpsielen, pwdinfo->device_name,
- pwdinfo->device_name_len);
- wpsielen += pwdinfo->device_name_len;
- }
-
- /* Config Method */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(pwdinfo->supported_wps_cm);
- wpsielen += 2;
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen,
- (unsigned char *)wpsie,
- &pattrib->pktlen);
-
- p2pielen = build_probe_resp_p2p_ie23a(pwdinfo, pframe);
- pframe += p2pielen;
- pattrib->pktlen += p2pielen;
- }
-
-#ifdef CONFIG_8723AU_P2P
- if (pwdinfo->wfd_info->wfd_enable) {
- wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
- } else if (pmlmepriv->wfd_probe_resp_ie &&
- pmlmepriv->wfd_probe_resp_ie_len > 0) {
- /* WFD IE */
- memcpy(pframe, pmlmepriv->wfd_probe_resp_ie,
- pmlmepriv->wfd_probe_resp_ie_len);
- pattrib->pktlen += pmlmepriv->wfd_probe_resp_ie_len;
- pframe += pmlmepriv->wfd_probe_resp_ie_len;
- }
-#endif /* CONFIG_8723AU_P2P */
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-
- return;
-}
-
-static int _issue23a_probereq_p2p(struct rtw_adapter *padapter, u8 *da,
- int wait_ack)
-{
- int ret = _FAIL;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- unsigned char *mac;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 wpsie[255] = {0x00}, p2pie[255] = {0x00};
- u16 wpsielen = 0, p2pielen = 0;
-#ifdef CONFIG_8723AU_P2P
- u32 wfdielen = 0;
-#endif /* CONFIG_8723AU_P2P */
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- 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);
-
- fctrl = &pwlanhdr->frame_control;
- *fctrl = 0;
-
- if (da) {
- ether_addr_copy(pwlanhdr->addr1, da);
- ether_addr_copy(pwlanhdr->addr3, da);
- } else {
- if ((pwdinfo->p2p_info.scan_op_ch_only) ||
- (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
- /* This two flags will be set when this is
- only the P2P client mode. */
- ether_addr_copy(pwlanhdr->addr1,
- pwdinfo->p2p_peer_interface_addr);
- ether_addr_copy(pwlanhdr->addr3,
- pwdinfo->p2p_peer_interface_addr);
- } 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);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_PROBEREQ);
-
- pframe += sizeof (struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof (struct ieee80211_hdr_3addr);
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
- pframe = rtw_set_ie23a(pframe, _SSID_IE_,
- pwdinfo->tx_prov_disc_info.ssid.ssid_len,
- pwdinfo->tx_prov_disc_info.ssid.ssid,
- &pattrib->pktlen);
- } else {
- pframe = rtw_set_ie23a(pframe, _SSID_IE_,
- P2P_WILDCARD_SSID_LEN,
- pwdinfo->p2p_wildcard_ssid,
- &pattrib->pktlen);
- }
- /* Use the OFDM rate in the P2P probe request frame.
- (6(B), 9(B), 12(B), 24(B), 36, 48, 54) */
- pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_, 8,
- pwdinfo->support_rate, &pattrib->pktlen);
-
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
- if (pmlmepriv->wps_probe_req_ie &&
- pmlmepriv->p2p_probe_req_ie) {
- /* WPS IE */
- memcpy(pframe, pmlmepriv->wps_probe_req_ie,
- pmlmepriv->wps_probe_req_ie_len);
- pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
- pframe += pmlmepriv->wps_probe_req_ie_len;
-
- /* P2P IE */
- memcpy(pframe, pmlmepriv->p2p_probe_req_ie,
- pmlmepriv->p2p_probe_req_ie_len);
- pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
- pframe += pmlmepriv->p2p_probe_req_ie_len;
- }
- } else {
-
- /* WPS IE */
- /* Noted by Albert 20110221 */
- /* According to the WPS specification, all the WPS
- attribute is presented by Big Endian. */
-
- wpsielen = 0;
- /* WPS OUI */
- *(u32*) (wpsie) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* WPS version */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
-
- if (pmlmepriv->wps_probe_req_ie == NULL) {
- /* UUID-E */
- /* Type: */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(WPS_ATTR_UUID_E);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0010);
- wpsielen += 2;
-
- /* Value: */
- memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv),
- ETH_ALEN);
- wpsielen += 0x10;
-
- /* Config Method */
- /* Type: */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(WPS_ATTR_CONF_METHOD);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(pwdinfo->supported_wps_cm);
- wpsielen += 2;
- }
-
- /* Device Name */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(pwdinfo->device_name_len);
- wpsielen += 2;
-
- /* Value: */
- memcpy(wpsie + wpsielen, pwdinfo->device_name,
- pwdinfo->device_name_len);
- wpsielen += pwdinfo->device_name_len;
-
- /* Primary Device Type */
- /* Type: */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0008);
- wpsielen += 2;
-
- /* Value: */
- /* Category ID */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_RTK_WIDI);
- wpsielen += 2;
-
- /* OUI */
- *(u32*) (wpsie + wpsielen) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* Sub Category ID */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_RTK_DMP);
- wpsielen += 2;
-
- /* Device Password ID */
- /* Type: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
- wpsielen += 2;
-
- /* Length: */
- *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
- /* Registrar-specified */
- *(u16*) (wpsie + wpsielen) =
- cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
- wpsielen += 2;
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen,
- (unsigned char *)wpsie,
- &pattrib->pktlen);
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20110221 */
- /* According to the P2P Specification, the probe request
- frame should contain 5 P2P attributes */
- /* 1. P2P Capability */
- /* 2. P2P Device ID if this probe request wants to
- find the specific P2P device */
- /* 3. Listen Channel */
- /* 4. Extended Listen Timing */
- /* 5. Operating Channel if this WiFi is working as
- the group owner now */
-
- /* P2P Capability */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported)
- p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP |
- DMP_P2P_GRPCAP_SUPPORT;
- else
- p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
-
- /* Listen Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
-
- /* Channel Number */
- /* listen channel */
- p2pie[p2pielen++] = pwdinfo->listen_channel;
-
- /* Extended Listen Timing */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0004);
- p2pielen += 2;
-
- /* Value: */
- /* Availability Period */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF);
- p2pielen += 2;
-
- /* Availability Interval */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF);
- p2pielen += 2;
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- /* Operating Channel (if this WiFi is working as
- the group owner now) */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute"
- section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
-
- /* Channel Number */
- /* operating channel number */
- p2pie[p2pielen++] = pwdinfo->operating_channel;
- }
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
- (unsigned char *)p2pie,
- &pattrib->pktlen);
-
- if (pmlmepriv->wps_probe_req_ie) {
- /* WPS IE */
- memcpy(pframe, pmlmepriv->wps_probe_req_ie,
- pmlmepriv->wps_probe_req_ie_len);
- pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
- pframe += pmlmepriv->wps_probe_req_ie_len;
- }
- }
-
-#ifdef CONFIG_8723AU_P2P
- if (pwdinfo->wfd_info->wfd_enable) {
- wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
- } else if (pmlmepriv->wfd_probe_req_ie &&
- pmlmepriv->wfd_probe_req_ie_len>0) {
- /* WFD IE */
- memcpy(pframe, pmlmepriv->wfd_probe_req_ie,
- pmlmepriv->wfd_probe_req_ie_len);
- pattrib->pktlen += pmlmepriv->wfd_probe_req_ie_len;
- pframe += pmlmepriv->wfd_probe_req_ie_len;
- }
-#endif /* CONFIG_8723AU_P2P */
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- ("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;
-}
-
-inline void issue23a_probereq_p2p(struct rtw_adapter *adapter, u8 *da)
-{
- _issue23a_probereq_p2p(adapter, da, false);
-}
-
-int issue23a_probereq_p2p_ex(struct rtw_adapter *adapter, u8 *da,
- int try_cnt, int wait_ms)
-{
- int ret;
- int i = 0;
- unsigned long start = jiffies;
-
- do {
- ret = _issue23a_probereq_p2p(adapter, da,
- wait_ms > 0 ? true : false);
-
- i++;
-
- if (adapter->bDriverStopped || adapter->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(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d "
- "in %u ms\n", FUNC_ADPT_ARG(adapter),
- MAC_ARG(da), rtw_get_oper_ch23a(adapter),
- ret == _SUCCESS?", acked":"", i, try_cnt,
- jiffies_to_msecs(jiffies - start));
- else
- DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
- FUNC_ADPT_ARG(adapter),
- rtw_get_oper_ch23a(adapter),
- ret == _SUCCESS?", acked":"", i, try_cnt,
- jiffies_to_msecs(jiffies - start));
- }
-exit:
- return ret;
-}
-
-#endif /* CONFIG_8723AU_P2P */
-
-static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token)
-{
- struct rtw_adapter *adapter = recv_frame->adapter;
- struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
- struct sk_buff *skb = recv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u16 seq_ctrl;
-
- seq_ctrl = ((recv_frame->attrib.seq_num&0xffff) << 4) |
- (recv_frame->attrib.frag_num & 0xf);
-
- if (ieee80211_has_retry(hdr->frame_control)) {
- if (token >= 0) {
- if ((seq_ctrl == mlmeext->action_public_rxseq) &&
- (token == mlmeext->action_public_dialog_token)) {
- DBG_8723A(FUNC_ADPT_FMT" seq_ctrl = 0x%x, "
- "rxseq = 0x%x, token:%d\n",
- FUNC_ADPT_ARG(adapter), seq_ctrl,
- mlmeext->action_public_rxseq, token);
- return _FAIL;
- }
- } else {
- if (seq_ctrl == mlmeext->action_public_rxseq) {
- DBG_8723A(FUNC_ADPT_FMT" seq_ctrl = 0x%x, "
- "rxseq = 0x%x\n",
- FUNC_ADPT_ARG(adapter), seq_ctrl,
- mlmeext->action_public_rxseq);
- return _FAIL;
- }
- }
- }
-
- mlmeext->action_public_rxseq = seq_ctrl;
-
- if (token >= 0)
- mlmeext->action_public_dialog_token = token;
-
- return _SUCCESS;
-}
-
-static unsigned int on_action_public23a_p2p(struct recv_frame *precv_frame)
-{
- struct sk_buff *skb = precv_frame->pkt;
- u8 *pframe = skb->data;
- u8 *frame_body;
- u8 dialogToken = 0;
-#ifdef CONFIG_8723AU_P2P
- struct rtw_adapter *padapter = precv_frame->adapter;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- uint len = skb->len;
- u8 *p2p_ie;
- u32 p2p_ielen;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 result = P2P_STATUS_SUCCESS;
-#endif /* CONFIG_8723AU_P2P */
-
- frame_body = (unsigned char *)
- (pframe + sizeof(struct ieee80211_hdr_3addr));
-
- dialogToken = frame_body[7];
-
- if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
- return _FAIL;
-
-#ifdef CONFIG_8723AU_P2P
- del_timer_sync(&pwdinfo->reset_ch_sitesurvey);
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
- rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
- } else {
- /* Do nothing if the driver doesn't enable the P2P function. */
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
- return _SUCCESS;
-
- len -= sizeof(struct ieee80211_hdr_3addr);
-
- switch (frame_body[ 6 ])/* OUI Subtype */
- {
- case P2P_GO_NEGO_REQ:
- DBG_8723A("[%s] Got GO Nego Req Frame\n", __func__);
- memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
- {
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
- }
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
- {
- /* Commented by Albert 20110526 */
- /* In this case, this means the previous nego fail doesn't be reset yet. */
- del_timer_sync(&pwdinfo->restore_p2p_state_timer);
- /* Restore the previous p2p state */
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
- DBG_8723A("[%s] Restore the previous p2p state to %d\n", __func__, rtw_p2p_state(pwdinfo));
- }
-
- /* Commented by Kurt 20110902 */
- /* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
- rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
-
- /* Commented by Kurt 20120113 */
- /* Get peer_dev_addr here if peer doesn't issue prov_disc frame. */
- if (is_zero_ether_addr(pwdinfo->rx_prov_disc_info.peerDevAddr))
- ether_addr_copy(pwdinfo->rx_prov_disc_info.peerDevAddr, hdr->addr2);
-
- result = process_p2p_group_negotation_req23a(pwdinfo, frame_body, len);
- issue_p2p_GO_response(padapter, hdr->addr2,
- frame_body, len, result);
-
- /* Commented by Albert 20110718 */
- /* No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */
- mod_timer(&pwdinfo->restore_p2p_state_timer,
- jiffies + msecs_to_jiffies(5000));
- break;
-
- case P2P_GO_NEGO_RESP:
- DBG_8723A("[%s] Got GO Nego Resp Frame\n", __func__);
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
- {
- /* Commented by Albert 20110425 */
- /* The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */
- del_timer_sync(&pwdinfo->restore_p2p_state_timer);
- pwdinfo->nego_req_info.benable = false;
- result = process_p2p_group_negotation_resp23a(pwdinfo, frame_body, len);
- issue_p2p_GO_confirm(pwdinfo->padapter,
- hdr->addr2,
- result);
- if (result == P2P_STATUS_SUCCESS) {
- if (rtw_p2p_role(pwdinfo) ==
- P2P_ROLE_CLIENT) {
- pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
- pwdinfo->p2p_info.scan_op_ch_only = 1;
- mod_timer(&pwdinfo->reset_ch_sitesurvey2, jiffies + msecs_to_jiffies(P2P_RESET_SCAN_CH));
- }
- }
-
- /* Reset the dialog token for group negotiation frames. */
- pwdinfo->negotiation_dialog_token = 1;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
- {
- mod_timer(&pwdinfo->restore_p2p_state_timer, jiffies + msecs_to_jiffies(5000));
- }
- } else {
- DBG_8723A("[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __func__);
- }
-
- break;
-
- case P2P_GO_NEGO_CONF:
-
- DBG_8723A("[%s] Got GO Nego Confirm Frame\n", __func__);
- result = process_p2p_group_negotation_confirm23a(pwdinfo, frame_body, len);
- if (P2P_STATUS_SUCCESS == result)
- {
- if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT)
- {
- pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
- pwdinfo->p2p_info.scan_op_ch_only = 1;
- mod_timer(&pwdinfo->reset_ch_sitesurvey2, jiffies + msecs_to_jiffies(P2P_RESET_SCAN_CH));
- }
- }
- break;
-
- case P2P_INVIT_REQ:
- /* Added by Albert 2010/10/05 */
- /* Received the P2P Invite Request frame. */
-
- DBG_8723A("[%s] Got invite request frame!\n", __func__);
- if ((p2p_ie = rtw_get_p2p_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)))
- {
- /* Parse the necessary information from the P2P Invitation Request frame. */
- /* For example: The MAC address of sending this P2P Invitation Request frame. */
- u32 attr_contentlen = 0;
- u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- struct group_id_info group_id;
- u8 invitation_flag = 0;
-
- rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
- if (attr_contentlen)
- {
-
- rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
- /* Commented by Albert 20120510 */
- /* Copy to the pwdinfo->p2p_peer_interface_addr. */
- /* So that the WFD UI (or Sigma) can get the peer interface address by using the following command. */
- /* #> iwpriv wlan0 p2p_get peer_ifa */
- /* After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */
-
- if (attr_contentlen)
- {
- DBG_8723A("[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __func__,
- pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
- pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
- pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
- }
-
- if (invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT)
- {
- /* Re-invoke the persistent group. */
-
- memset(&group_id, 0x00, sizeof(struct group_id_info));
- rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8*) &group_id, &attr_contentlen);
- if (attr_contentlen) {
- if (ether_addr_equal(group_id.go_device_addr, myid(&padapter->eeprompriv))) {
- /* The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- status_code = P2P_STATUS_SUCCESS;
- }
- else
- {
- /* The p2p device sending this p2p invitation request wants to be the persistent GO. */
- if (is_matched_in_profilelist(pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ]))
- {
- u8 operatingch_info[5] = { 0x00 };
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
- {
- if (rtw_ch_set_search_ch23a(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4]))
- {
- /* The operating channel is acceptable for this device. */
- pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
- pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
- mod_timer(&pwdinfo->reset_ch_sitesurvey, jiffies + msecs_to_jiffies(P2P_RESET_SCAN_CH));
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- status_code = P2P_STATUS_SUCCESS;
- }
- else
- {
- /* The operating channel isn't supported by this device. */
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
- mod_timer(&pwdinfo->restore_p2p_state_timer, jiffies + msecs_to_jiffies(3000));
- }
- }
- else {
- /* Commented by Albert 20121130 */
- /* Intel will use the different P2P IE to store the operating channel information */
- /* Workaround for Intel WiDi 3.5 */
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- status_code = P2P_STATUS_SUCCESS;
- }
- }
- else
- {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
-
- status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
- }
- }
- }
- else
- {
- DBG_8723A("[%s] P2P Group ID Attribute NOT FOUND!\n", __func__);
- status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- }
- }
- else
- {
- /* Received the invitation to join a P2P group. */
-
- memset(&group_id, 0x00, sizeof(struct group_id_info));
- rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8*) &group_id, &attr_contentlen);
- if (attr_contentlen)
- {
- if (ether_addr_equal(group_id.go_device_addr, myid(&padapter->eeprompriv))) {
- /* In this case, the GO can't be myself. */
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
- status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- }
- else
- {
- /* The p2p device sending this p2p invitation request wants to join an existing P2P group */
- /* Commented by Albert 2012/06/28 */
- /* In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */
- /* The peer device address should be the destination address for the provisioning discovery request. */
- /* Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */
- /* The peer interface address should be the address for WPS mac address */
- ether_addr_copy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN);
- status_code = P2P_STATUS_SUCCESS;
- }
- }
- else
- {
- DBG_8723A("[%s] P2P Group ID Attribute NOT FOUND!\n", __func__);
- status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- }
- }
- }
- else
- {
- DBG_8723A("[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __func__);
- status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- }
-
- DBG_8723A("[%s] status_code = %d\n", __func__, status_code);
-
- pwdinfo->inviteresp_info.token = frame_body[ 7 ];
- issue_p2p_invitation_response23a(padapter, hdr->addr2, pwdinfo->inviteresp_info.token, status_code);
- }
- break;
-
- case P2P_INVIT_RESP:
- {
- u8 attr_content = 0x00;
- u32 attr_contentlen = 0;
-
- DBG_8723A("[%s] Got invite response frame!\n", __func__);
- del_timer_sync(&pwdinfo->restore_p2p_state_timer);
- if ((p2p_ie = rtw_get_p2p_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)))
- {
- rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
-
- if (attr_contentlen == 1)
- {
- DBG_8723A("[%s] Status = %d\n", __func__, attr_content);
- pwdinfo->invitereq_info.benable = false;
-
- if (attr_content == P2P_STATUS_SUCCESS)
- {
- if (ether_addr_equal(pwdinfo->invitereq_info.go_bssid, myid(&padapter->eeprompriv))) {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- }
- else
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- }
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_OK);
- }
- else
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
- }
- }
- else
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
- }
- }
- else
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
- }
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL)) {
- mod_timer(&pwdinfo->restore_p2p_state_timer, jiffies + msecs_to_jiffies(5000));
- }
- break;
- }
- case P2P_DEVDISC_REQ:
-
- process_p2p_devdisc_req23a(pwdinfo, pframe, len);
-
- break;
-
- case P2P_DEVDISC_RESP:
-
- process_p2p_devdisc_resp23a(pwdinfo, pframe, len);
-
- break;
-
- case P2P_PROVISION_DISC_REQ:
- DBG_8723A("[%s] Got Provisioning Discovery Request Frame\n", __func__);
- process_p2p_provdisc_req23a(pwdinfo, pframe, len);
- ether_addr_copy(pwdinfo->rx_prov_disc_info.peerDevAddr, hdr->addr2);
-
- /* 20110902 Kurt */
- /* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
- rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
-
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
- mod_timer(&pwdinfo->restore_p2p_state_timer,
- jiffies + msecs_to_jiffies(P2P_PROVISION_TIMEOUT));
- break;
-
- case P2P_PROVISION_DISC_RESP:
- /* Commented by Albert 20110707 */
- /* Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */
- DBG_8723A("[%s] Got Provisioning Discovery Response Frame\n", __func__);
- /* Commented by Albert 20110426 */
- /* The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */
- del_timer_sync(&pwdinfo->restore_p2p_state_timer);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
- process_p2p_provdisc_resp23a(pwdinfo, pframe);
- mod_timer(&pwdinfo->restore_p2p_state_timer,
- jiffies + msecs_to_jiffies(P2P_PROVISION_TIMEOUT));
- break;
-
- }
- }
-#endif /* CONFIG_8723AU_P2P */
-
- return _SUCCESS;
-}
-
-static unsigned int on_action_public23a_vendor(struct recv_frame *precv_frame)
-{
- unsigned int ret = _FAIL;
- struct sk_buff *skb = precv_frame->pkt;
- u8 *pframe = skb->data;
- u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
-
- if (!memcmp(frame_body + 2, P2P_OUI23A, 4)) {
- ret = on_action_public23a_p2p(precv_frame);
- }
-
- return ret;
-}
-
-static unsigned int
-on_action_public23a_default(struct recv_frame *precv_frame, u8 action)
-{
- unsigned int ret = _FAIL;
- struct sk_buff *skb = precv_frame->pkt;
- u8 *pframe = skb->data;
- uint frame_len = skb->len;
- u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
- u8 token;
- struct rtw_adapter *adapter = precv_frame->adapter;
- int cnt = 0;
- char msg[64];
-
- token = frame_body[2];
-
- if (rtw_action_public_decache(precv_frame, token) == _FAIL)
- goto exit;
-
- cnt += sprintf((msg+cnt), "%s(token:%u)",
- action_public_str23a(action), token);
- rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
-
- ret = _SUCCESS;
-
-exit:
- return ret;
-}
-
-unsigned int on_action_public23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
- unsigned int ret = _FAIL;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u8 *pframe = skb->data;
- u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
- u8 category, action;
-
- /* check RA matches or not */
- if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
- goto exit;
-
- category = frame_body[0];
- if (category != WLAN_CATEGORY_PUBLIC)
- goto exit;
-
- action = frame_body[1];
- switch (action) {
- case ACT_PUBLIC_VENDOR:
- ret = on_action_public23a_vendor(precv_frame);
- break;
- default:
- ret = on_action_public23a_default(precv_frame, action);
- break;
- }
-
-exit:
- return ret;
-}
-
-unsigned int OnAction23a_ht(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
- return _SUCCESS;
-}
-
-unsigned int OnAction23a_wmm(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
+static int
+OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
return _SUCCESS;
-}
-
-unsigned int OnAction23a_p2p(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
-#ifdef CONFIG_8723AU_P2P
- u8 *frame_body;
- u8 category, OUI_Subtype, dialogToken = 0;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u8 *pframe = skb->data;
- uint len = skb->len;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- DBG_8723A("%s\n", __func__);
-
- /* check RA matches or not */
- if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
- return _SUCCESS;
-
- frame_body = (unsigned char *)
- (pframe + sizeof(struct ieee80211_hdr_3addr));
-
- category = frame_body[0];
- if (category != WLAN_CATEGORY_VENDOR_SPECIFIC)
- return _SUCCESS;
-
- if (cpu_to_be32(*((u32*) (frame_body + 1))) != P2POUI)
- return _SUCCESS;
-
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
- rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
- return _SUCCESS;
- } else {
- len -= sizeof(struct ieee80211_hdr_3addr);
- OUI_Subtype = frame_body[5];
- dialogToken = frame_body[6];
-
- switch (OUI_Subtype)
- {
- case P2P_NOTICE_OF_ABSENCE:
- break;
-
- case P2P_PRESENCE_REQUEST:
- process_p2p_presence_req23a(pwdinfo, pframe, len);
- break;
-
- case P2P_PRESENCE_RESPONSE:
- break;
-
- case P2P_GO_DISC_REQUEST:
- break;
+}
- default:
- break;
- }
- }
-#endif /* CONFIG_8723AU_P2P */
+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;
}
-unsigned int OnAction23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
+static int
+OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
int i;
- unsigned char category;
+ u8 category;
struct action_handler *ptable;
- unsigned char *frame_body;
struct sk_buff *skb = precv_frame->pkt;
- u8 *pframe = skb->data;
-
- frame_body = (unsigned char *)
- (pframe + sizeof(struct ieee80211_hdr_3addr));
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- category = frame_body[0];
+ category = mgmt->u.action.category;
for (i = 0;
i < sizeof(OnAction23a_tbl) / sizeof(struct action_handler); i++) {
return _SUCCESS;
}
-unsigned int DoReserved23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
+static int DoReserved23a(struct rtw_adapter *padapter,
+ struct recv_frame *precv_frame)
{
return _SUCCESS;
}
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
unsigned int rate_len;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
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};
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif /* CONFIG_8723AU_P2P */
u8 *wps_ie;
u32 wps_ielen;
u8 sr = 0;
if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
/* DBG_8723A("ie len =%d\n", cur_network->IELength); */
-#ifdef CONFIG_8723AU_P2P
- /* for P2P : Primary Device Type & Device Name */
- u32 insert_len = 0;
- wps_ie = rtw_get_wps_ie23a(cur_network->IEs + _FIXED_IE_LENGTH_,
- cur_network->IELength -
- _FIXED_IE_LENGTH_, NULL, &wps_ielen);
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wps_ie &&
- wps_ielen > 0) {
- uint wps_offset, remainder_ielen;
- u8 *premainder_ie, *pframe_wscie;
-
- wps_offset = (uint)(wps_ie - cur_network->IEs);
-
- premainder_ie = wps_ie + wps_ielen;
-
- remainder_ielen = cur_network->IELength - wps_offset -
- wps_ielen;
-
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
- if (pmlmepriv->wps_beacon_ie &&
- pmlmepriv->wps_beacon_ie_len>0) {
- memcpy(pframe, cur_network->IEs,
- wps_offset);
- pframe += wps_offset;
- pattrib->pktlen += wps_offset;
-
- memcpy(pframe, pmlmepriv->wps_beacon_ie,
- pmlmepriv->wps_beacon_ie_len);
- pframe += pmlmepriv->wps_beacon_ie_len;
- pattrib->pktlen +=
- pmlmepriv->wps_beacon_ie_len;
-
- /* copy remainder_ie to pframe */
- memcpy(pframe, premainder_ie,
- remainder_ielen);
- pframe += remainder_ielen;
- pattrib->pktlen += remainder_ielen;
- } else {
- memcpy(pframe, cur_network->IEs,
- cur_network->IELength);
- pframe += cur_network->IELength;
- pattrib->pktlen +=
- cur_network->IELength;
- }
- } else {
- pframe_wscie = pframe + wps_offset;
- memcpy(pframe, cur_network->IEs,
- wps_offset + wps_ielen);
- pframe += (wps_offset + wps_ielen);
- pattrib->pktlen += (wps_offset + wps_ielen);
-
- /* now pframe is end of wsc ie, insert Primary
- Device Type & Device Name */
- /* Primary Device Type */
- /* Type: */
- *(u16*) (pframe + insert_len) =
- cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
- insert_len += 2;
-
- /* Length: */
- *(u16*) (pframe + insert_len) =
- cpu_to_be16(0x0008);
- insert_len += 2;
-
- /* Value: */
- /* Category ID */
- *(u16*) (pframe + insert_len) =
- cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
- insert_len += 2;
-
- /* OUI */
- *(u32*) (pframe + insert_len) =
- cpu_to_be32(WPSOUI);
- insert_len += 4;
-
- /* Sub Category ID */
- *(u16*) (pframe + insert_len) =
- cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
- insert_len += 2;
-
- /* Device Name */
- /* Type: */
- *(u16*) (pframe + insert_len) =
- cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- insert_len += 2;
-
- /* Length: */
- *(u16*) (pframe + insert_len) =
- cpu_to_be16(pwdinfo->device_name_len);
- insert_len += 2;
-
- /* Value: */
- memcpy(pframe + insert_len,
- pwdinfo->device_name,
- pwdinfo->device_name_len);
- insert_len += pwdinfo->device_name_len;
-
- /* update wsc ie length */
- *(pframe_wscie+1) = (wps_ielen -2) + insert_len;
-
- /* pframe move to end */
- pframe+= insert_len;
- pattrib->pktlen += insert_len;
-
- /* copy remainder_ie to pframe */
- memcpy(pframe, premainder_ie, remainder_ielen);
- pframe += remainder_ielen;
- pattrib->pktlen += remainder_ielen;
- }
- } else
-#endif /* CONFIG_8723AU_P2P */
- memcpy(pframe, cur_network->IEs, cur_network->IELength);
+ memcpy(pframe, cur_network->IEs, cur_network->IELength);
len_diff = update_hidden_ssid(pframe + _BEACON_IE_OFFSET_,
cur_network->IELength -
_BEACON_IE_OFFSET_,
else
_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
-#ifdef CONFIG_8723AU_P2P
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- u32 len;
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
- len = pmlmepriv->p2p_beacon_ie_len;
- if (pmlmepriv->p2p_beacon_ie && len > 0)
- memcpy(pframe,
- pmlmepriv->p2p_beacon_ie, len);
- } else
- len = build_beacon_p2p_ie23a(pwdinfo, pframe);
-
- pframe += len;
- pattrib->pktlen += len;
-
- if (true == pwdinfo->wfd_info->wfd_enable) {
- len = build_beacon_wfd_ie(pwdinfo, pframe);
- } else {
- len = 0;
- if (pmlmepriv->wfd_beacon_ie &&
- pmlmepriv->wfd_beacon_ie_len>0) {
- len = pmlmepriv->wfd_beacon_ie_len;
- memcpy(pframe,
- pmlmepriv->wfd_beacon_ie, len);
- }
- }
- pframe += len;
- pattrib->pktlen += len;
- }
-#endif /* CONFIG_8723AU_P2P */
-
goto _issue_bcn;
}
pattrib->pktlen += 2;
/* SSID */
- pframe = rtw_set_ie23a(pframe, _SSID_IE_, cur_network->Ssid.ssid_len,
+ 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, _SUPPORTEDRATES_IE_,
+ 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, _DSSET_IE_, 1, (unsigned char *)
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
&cur_network->Configuration.DSConfig,
&pattrib->pktlen);
/* IBSS Parameter Set... */
/* ATIMWindow = cur->Configuration.ATIMWindow; */
ATIMWindow = 0;
- pframe = rtw_set_ie23a(pframe, _IBSS_PARA_IE_, 2,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
(unsigned char *)&ATIMWindow,
&pattrib->pktlen);
/* ERP IE */
- pframe = rtw_set_ie23a(pframe, _ERPINFO_IE_, 1,
+ 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, _EXT_SUPPORTEDRATES_IE_,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
rate_len - 8,
cur_network->SupportedRates + 8,
&pattrib->pktlen);
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
unsigned char *mac, *bssid;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
#ifdef CONFIG_8723AU_AP_MODE
int ssid_ielen_diff;
u8 buf[MAX_IE_SZ];
u8 *ies;
-#endif
-#if defined(CONFIG_8723AU_AP_MODE) || defined(CONFIG_8723AU_P2P)
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
#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;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif /* CONFIG_8723AU_P2P */
/* DBG_8723A("%s\n", __func__); */
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- {
+ pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
+ if (!pmgntframe) {
DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
return;
}
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
+ pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
pwlanhdr = (struct ieee80211_hdr *)pframe;
mac = myid(&padapter->eeprompriv);
&wps_ielen);
/* inerset & update wps_probe_resp_ie */
- if ((pmlmepriv->wps_probe_resp_ie != NULL) && pwps_ie &&
- (wps_ielen > 0)) {
+ if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) {
uint wps_offset, remainder_ielen;
u8 *premainder_ie;
/* to get ie data len */
wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];
- if ((wps_offset+wps_ielen+2)<= MAX_IE_SZ) {
+ if (wps_offset + wps_ielen + 2 <= MAX_IE_SZ) {
memcpy(pframe, pmlmepriv->wps_probe_resp_ie,
wps_ielen+2);
pframe += wps_ielen+2;
pattrib->pktlen += wps_ielen+2;
}
- if ((wps_offset+wps_ielen+2+remainder_ielen) <=
+ if (wps_offset + wps_ielen + 2 + remainder_ielen <=
MAX_IE_SZ) {
memcpy(pframe, premainder_ie, remainder_ielen);
pframe += remainder_ielen;
ies = pmgntframe->buf_addr + TXDESC_OFFSET +
sizeof(struct ieee80211_hdr_3addr);
- ssid_ie = rtw_get_ie23a(ies+_FIXED_IE_LENGTH_, _SSID_IE_,
+ ssid_ie = rtw_get_ie23a(ies + _FIXED_IE_LENGTH_, WLAN_EID_SSID,
&ssid_ielen,
- (pframe-ies)-_FIXED_IE_LENGTH_);
+ pframe - ies - _FIXED_IE_LENGTH_);
ssid_ielen_diff = cur_network->Ssid.ssid_len - ssid_ielen;
uint remainder_ielen;
u8 *remainder_ie;
remainder_ie = ssid_ie + 2;
- remainder_ielen = (pframe-remainder_ie);
+ remainder_ielen = pframe - remainder_ie;
DBG_8723A_LEVEL(_drv_warning_, FUNC_ADPT_FMT
" remainder_ielen > MAX_IE_SZ\n",
FUNC_ADPT_ARG(padapter));
- if (remainder_ielen > MAX_IE_SZ) {
+ if (remainder_ielen > MAX_IE_SZ)
remainder_ielen = MAX_IE_SZ;
- }
memcpy(buf, remainder_ie, remainder_ielen);
- memcpy(remainder_ie+ssid_ielen_diff, buf,
+ 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,
+ *(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;
/* below for ad-hoc mode */
/* SSID */
- pframe = rtw_set_ie23a(pframe, _SSID_IE_,
- cur_network->Ssid.ssid_len,
- cur_network->Ssid.ssid, &pattrib->pktlen);
+ 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, _SUPPORTEDRATES_IE_,
+ 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, _DSSET_IE_, 1, (unsigned char *)
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1,
+ (unsigned char *)
&cur_network->Configuration.DSConfig,
&pattrib->pktlen);
- if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
+ if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
u8 erpinfo = 0;
u32 ATIMWindow;
/* IBSS Parameter Set... */
/* ATIMWindow = cur->Configuration.ATIMWindow; */
ATIMWindow = 0;
- pframe = rtw_set_ie23a(pframe, _IBSS_PARA_IE_, 2,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
(unsigned char *)&ATIMWindow,
&pattrib->pktlen);
/* ERP IE */
- pframe = rtw_set_ie23a(pframe, _ERPINFO_IE_, 1,
+ 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, _EXT_SUPPORTEDRATES_IE_,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
rate_len - 8,
cur_network->SupportedRates + 8,
&pattrib->pktlen);
/* todo:HT for adhoc */
}
-#ifdef CONFIG_8723AU_P2P
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && is_valid_p2p_probereq) {
- u32 len;
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
- /* if pwdinfo->role == P2P_ROLE_DEVICE will call
- issue_probersp23a_p2p23a() */
- len = pmlmepriv->p2p_go_probe_resp_ie_len;
- if (pmlmepriv->p2p_go_probe_resp_ie && len>0)
- memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie,
- len);
- } else
- len = build_probe_resp_p2p_ie23a(pwdinfo, pframe);
-
- pframe += len;
- pattrib->pktlen += len;
-
- if (true == pwdinfo->wfd_info->wfd_enable) {
- len = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
- } else {
- len = 0;
- if (pmlmepriv->wfd_probe_resp_ie &&
- pmlmepriv->wfd_probe_resp_ie_len > 0) {
- len = pmlmepriv->wfd_probe_resp_ie_len;
- memcpy(pframe, pmlmepriv->wfd_probe_resp_ie,
- len);
- }
- }
- pframe += len;
- pattrib->pktlen += len;
- }
-#endif /* CONFIG_8723AU_P2P */
-
pattrib->last_txcmdsz = pattrib->pktlen;
dump_mgntframe23a(padapter, pmgntframe);
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
unsigned char *mac;
unsigned char bssrate[NumRates];
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
mac = myid(&padapter->eeprompriv);
- fctrl = &pwlanhdr->frame_control;
+ fctrl = &pwlanhdr->frame_control;
*fctrl = 0;
if (da) {
pattrib->pktlen = sizeof (struct ieee80211_hdr_3addr);
if (pssid)
- pframe = rtw_set_ie23a(pframe, _SSID_IE_, pssid->ssid_len,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, pssid->ssid_len,
pssid->ssid, &pattrib->pktlen);
else
- pframe = rtw_set_ie23a(pframe, _SSID_IE_, 0, NULL,
+ 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, _SUPPORTEDRATES_IE_, 8,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
bssrate, &pattrib->pktlen);
- pframe = rtw_set_ie23a(pframe, _EXT_SUPPORTEDRATES_IE_,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
(bssrate_len - 8), (bssrate + 8),
&pattrib->pktlen);
} else {
- pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
bssrate_len, bssrate, &pattrib->pktlen);
}
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
unsigned int val32;
unsigned short val16;
int use_shared_key = 0;
/* added challenging text... */
if ((psta->auth_seq == 2) &&
(psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
- pframe = rtw_set_ie23a(pframe, _CHLGETXT_IE_, 128,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
psta->chg_txt, &pattrib->pktlen);
#endif
} else {
if ((pmlmeinfo->auth_seq == 3) &&
(pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
(use_shared_key == 1)) {
- pframe = rtw_set_ie23a(pframe, _CHLGETXT_IE_, 128,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
pmlmeinfo->chg_txt,
&pattrib->pktlen);
struct xmit_frame *pmgntframe;
struct ieee80211_hdr *pwlanhdr;
struct pkt_attrib *pattrib;
- unsigned char *pbuf, *pframe;
+ unsigned char *pframe;
unsigned short val;
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;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u32 wfdielen = 0;
-#endif /* CONFIG_8723AU_P2P */
DBG_8723A("%s\n", __func__);
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
+ pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
+ if (!pmgntframe)
return;
/* update attribute */
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
- if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
+ if (pkt_type == WIFI_ASSOCRSP || pkt_type == WIFI_REASSOCRSP)
SetFrameSubType(pwlanhdr, pkt_type);
else
return;
&pattrib->pktlen);
if (pstat->bssratelen <= 8) {
- pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
pstat->bssratelen, pstat->bssrateset,
&pattrib->pktlen);
} else {
- pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_, 8,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
pstat->bssrateset, &pattrib->pktlen);
- pframe = rtw_set_ie23a(pframe, _EXT_SUPPORTEDRATES_IE_,
+ 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)) {
- uint ie_len = 0;
-
+ if (pstat->flags & WLAN_STA_HT && pmlmepriv->htpriv.ht_option) {
/* FILL HT CAP INFO IE */
/* p = hostapd_eid_ht_capabilities_info(hapd, p); */
- pbuf = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_,
- _HT_CAPABILITY_IE_, &ie_len,
- pnetwork->IELength - _BEACON_IE_OFFSET_);
- if (pbuf && ie_len>0) {
- memcpy(pframe, pbuf, ie_len + 2);
- pframe += (ie_len + 2);
- pattrib->pktlen += (ie_len + 2);
+ p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
+ ie + _BEACON_IE_OFFSET_,
+ pnetwork->IELength -_BEACON_IE_OFFSET_);
+ 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); */
- pbuf = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_,
- &ie_len,
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
+ ie + _BEACON_IE_OFFSET_,
pnetwork->IELength - _BEACON_IE_OFFSET_);
- if (pbuf && ie_len > 0) {
- memcpy(pframe, pbuf, ie_len + 2);
- pframe += (ie_len + 2);
- pattrib->pktlen += (ie_len + 2);
+ 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->qospriv.qos_option) {
- uint ie_len = 0;
+ if (pstat->flags & WLAN_STA_WME && pmlmepriv->qospriv.qos_option) {
unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02,
0x01, 0x01};
-
- for (pbuf = ie + _BEACON_IE_OFFSET_; ; pbuf += (ie_len + 2)) {
- pbuf = rtw_get_ie23a(pbuf, _VENDOR_SPECIFIC_IE_,
- &ie_len, (pnetwork->IELength -
- _BEACON_IE_OFFSET_ -
- (ie_len + 2)));
- if (pbuf && !memcmp(pbuf + 2, WMM_PARA_IE, 6)) {
- memcpy(pframe, pbuf, ie_len + 2);
+ int ie_len = 0;
+
+ for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
+ p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p,
+ pnetwork->IELength -
+ _BEACON_IE_OFFSET_ - (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 ((!pbuf) || (ie_len == 0))
+ if (!p || ie_len == 0)
break;
}
}
if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, 6,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
REALTEK_96B_IE23A, &pattrib->pktlen);
}
pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
}
-#ifdef CONFIG_8723AU_P2P
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) &&
- pwdinfo->wfd_info->wfd_enable) {
- wfdielen = build_assoc_resp_wfd_ie(pwdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
- }
-#endif /* CONFIG_8723AU_P2P */
-
pattrib->last_txcmdsz = pattrib->pktlen;
dump_mgntframe23a(padapter, pmgntframe);
int ret = _FAIL;
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
- unsigned char *pframe, *p;
+ unsigned char *pframe;
+ const u8 *p;
struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- unsigned short val16;
- unsigned int i, j, ie_len, index = 0;
+ __le16 *fctrl;
+ unsigned int i, j, index = 0;
unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
struct ndis_802_11_var_ies *pIE;
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;
- int bssrate_len = 0, sta_bssrate_len = 0;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 p2pie[255] = { 0x00 };
- u16 p2pielen = 0;
- u32 wfdielen = 0;
-#endif /* CONFIG_8723AU_P2P */
+ int bssrate_len = 0, sta_bssrate_len = 0, pie_len;
+ u8 * pie;
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
+ pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
+ if (!pmgntframe)
goto exit;
/* update attribute */
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
+ pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
pwlanhdr = (struct ieee80211_hdr *)pframe;
fctrl = &pwlanhdr->frame_control;
pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
/* caps */
- memcpy(pframe, rtw_get_capability23a_from_ie(pmlmeinfo->network.IEs),
- 2);
+ memcpy(pframe,
+ rtw_get_capability23a_from_ie(pmlmeinfo->network.IEs), 2);
pframe += 2;
pattrib->pktlen += 2;
/* listen interval */
/* todo: listen interval for power saving */
- val16 = cpu_to_le16(3);
- memcpy(pframe, (unsigned char *)&val16, 2);
+ put_unaligned_le16(3, pframe);
pframe += 2;
pattrib->pktlen += 2;
/* SSID */
- pframe = rtw_set_ie23a(pframe, _SSID_IE_,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
pmlmeinfo->network.Ssid.ssid_len,
pmlmeinfo->network.Ssid.ssid, &pattrib->pktlen);
Handlink WSG-4000 AP */
if ((pmlmeinfo->network.SupportedRates[i] |
IEEE80211_BASIC_RATE_MASK) ==
- (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
+ (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
/* DBG_8723A("match i = %d, j =%d\n", i, j); */
break;
}
}
if (bssrate_len > 8) {
- pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_, 8,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
bssrate, &pattrib->pktlen);
- pframe = rtw_set_ie23a(pframe, _EXT_SUPPORTEDRATES_IE_,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
(bssrate_len - 8), (bssrate + 8),
&pattrib->pktlen);
} else
- pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
bssrate_len, bssrate, &pattrib->pktlen);
/* RSN */
- p = rtw_get_ie23a((pmlmeinfo->network.IEs +
- sizeof(struct ndis_802_11_fixed_ies)), _RSN_IE_2_,
- &ie_len, (pmlmeinfo->network.IELength -
- sizeof(struct ndis_802_11_fixed_ies)));
+ pie = pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ies);
+ pie_len = pmlmeinfo->network.IELength -
+ sizeof(struct ndis_802_11_fixed_ies);
+
+ p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
if (p)
- pframe = rtw_set_ie23a(pframe, _RSN_IE_2_, ie_len, (p + 2),
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_RSN, p[1], p + 2,
&pattrib->pktlen);
/* HT caps */
if (padapter->mlmepriv.htpriv.ht_option == true) {
- p = rtw_get_ie23a((pmlmeinfo->network.IEs +
- sizeof(struct ndis_802_11_fixed_ies)),
- _HT_CAPABILITY_IE_, &ie_len,
- (pmlmeinfo->network.IELength -
- sizeof(struct ndis_802_11_fixed_ies)));
- if ((p != NULL) && (!(is_ap_in_tkip23a(padapter)))) {
- memcpy(&pmlmeinfo->HT_caps, (p + 2),
+ p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, pie_len);
+
+ if (p && !is_ap_in_tkip23a(padapter)) {
+ memcpy(&pmlmeinfo->HT_caps, p + 2,
sizeof(struct HT_caps_element));
/* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |=
0x000c;
- rtw23a_hal_get_hwreg(padapter, HW_VAR_RF_TYPE,
- (u8 *)(&rf_type));
+ rf_type = rtl8723a_get_rf_type(padapter);
/* switch (pregpriv->rf_config) */
- switch (rf_type)
- {
+ switch (rf_type) {
case RF_1T1R:
-
+ /* RX STBC One spatial stream */
if (pregpriv->rx_stbc)
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);/* RX STBC One spatial stream */
+ pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);
memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, 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) &&
+ 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)) ||
+ pregpriv->rx_stbc == 0x1) ||
+ (pmlmeext->cur_wireless_mode &
+ WIRELESS_11_5N &&
+ pregpriv->rx_stbc == 0x2) ||
/* enable for 5GHz */
- (pregpriv->wifi_spec == 1)) {
+ pregpriv->wifi_spec == 1) {
DBG_8723A("declare supporting RX "
"STBC\n");
pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
}
#endif
- pframe = rtw_set_ie23a(pframe, _HT_CAPABILITY_IE_,
- ie_len,
- (u8 *)&pmlmeinfo->HT_caps,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_HT_CAPABILITY,
+ p[1], (u8 *)&pmlmeinfo->HT_caps,
&pattrib->pktlen);
}
}
switch (pIE->ElementID)
{
- case _VENDOR_SPECIFIC_IE_:
- if (!memcmp(pIE->data, RTW_WPA_OUI23A, 4) ||
+ case WLAN_EID_VENDOR_SPECIFIC:
+ if (!memcmp(pIE->data, RTW_WPA_OUI23A_TYPE, 4) ||
!memcmp(pIE->data, WMM_OUI23A, 4) ||
!memcmp(pIE->data, WPS_OUI23A, 4)) {
if (!padapter->registrypriv.wifi_spec) {
pIE->Length = 14;
}
pframe = rtw_set_ie23a(pframe,
- _VENDOR_SPECIFIC_IE_,
+ WLAN_EID_VENDOR_SPECIFIC,
pIE->Length, pIE->data,
&pattrib->pktlen);
}
break;
}
- i += (pIE->Length + 2);
+ i += pIE->Length + 2;
}
if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, 6,
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
REALTEK_96B_IE23A, &pattrib->pktlen);
-#ifdef CONFIG_8723AU_P2P
-
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
- if (pmlmepriv->p2p_assoc_req_ie &&
- pmlmepriv->p2p_assoc_req_ie_len>0) {
- memcpy(pframe, pmlmepriv->p2p_assoc_req_ie,
- pmlmepriv->p2p_assoc_req_ie_len);
- pframe += pmlmepriv->p2p_assoc_req_ie_len;
- pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
- }
- } else {
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
- !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
- /* Should add the P2P IE in the association
- request frame. */
- /* P2P OUI */
-
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20101109 */
- /* According to the P2P Specification, the
- association request frame should contain
- 3 P2P attributes */
- /* 1. P2P Capability */
- /* 2. Extended Listen Timing */
- /* 3. Device Info */
- /* Commented by Albert 20110516 */
- /* 4. P2P Interface */
-
- /* P2P Capability */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported)
- p2pie[p2pielen++] =
- P2P_GRPCAP_PERSISTENT_GROUP |
- DMP_P2P_GRPCAP_SUPPORT;
- else
- p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
-
- /* Extended Listen Timing */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0004);
- p2pielen += 2;
-
- /* Value: */
- /* Availability Period */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF);
- p2pielen += 2;
-
- /* Availability Interval */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF);
- p2pielen += 2;
-
- /* Device Info */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* 21 -> P2P Device Address (6bytes) + Config
- Methods (2bytes) + Primary Device
- Type (8bytes) */
- /* + NumofSecondDevType (1byte) + WPS Device
- Name ID field (2bytes) + WPS Device Name
- Len field (2bytes) */
- *(u16*) (p2pie + p2pielen) =
- cpu_to_le16(21 + pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address */
- memcpy(p2pie + p2pielen,
- myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Config Method */
- /* This field should be big endian.
- Noted by P2P specification. */
- if ((pwdinfo->ui_got_wps_info ==
- P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) ||
- (pwdinfo->ui_got_wps_info ==
- P2P_GOT_WPSINFO_SELF_DISPLAY_PIN))
- *(u16*) (p2pie + p2pielen) =
- cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
- else
- *(u16*) (p2pie + p2pielen) =
- cpu_to_be16(WPS_CONFIG_METHOD_PBC);
-
- p2pielen += 2;
-
- /* Primary Device Type */
- /* Category ID */
- *(u16*) (p2pie + p2pielen) =
- cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
- p2pielen += 2;
-
- /* OUI */
- *(u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI);
- p2pielen += 4;
-
- /* Sub Category ID */
- *(u16*) (p2pie + p2pielen) =
- cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
- p2pielen += 2;
-
- /* Number of Secondary Device Types */
- /* No Secondary Device Type List */
- p2pie[p2pielen++] = 0x00;
-
- /* Device Name */
- /* Type: */
- *(u16*) (p2pie + p2pielen) =
- cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- p2pielen += 2;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) =
- cpu_to_be16(pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_name,
- pwdinfo->device_name_len);
- p2pielen += pwdinfo->device_name_len;
-
- /* P2P Interface */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_INTERFACE;
-
- /* Length: */
- *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x000D);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_addr,
- ETH_ALEN); /* P2P Device Address */
- p2pielen += ETH_ALEN;
-
- /* P2P Interface Address Count */
- p2pie[p2pielen++] = 1;
-
- memcpy(p2pie + p2pielen, pwdinfo->device_addr,
- ETH_ALEN); /* P2P Interface Address List */
- p2pielen += ETH_ALEN;
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_,
- p2pielen, (unsigned char *)p2pie,
- &pattrib->pktlen);
-
- /* wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);*/
- /* pframe += wfdielen; */
- /* pattrib->pktlen += wfdielen; */
- }
- }
-
- if (true == pwdinfo->wfd_info->wfd_enable) {
- wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
- } else if (pmlmepriv->wfd_assoc_req_ie != NULL &&
- pmlmepriv->wfd_assoc_req_ie_len > 0) {
- /* WFD IE */
- memcpy(pframe, pmlmepriv->wfd_assoc_req_ie,
- pmlmepriv->wfd_assoc_req_ie_len);
- pattrib->pktlen += pmlmepriv->wfd_assoc_req_ie_len;
- pframe += pmlmepriv->wfd_assoc_req_ie_len;
- }
-#endif /* CONFIG_8723AU_P2P */
-
pattrib->last_txcmdsz = pattrib->pktlen;
dump_mgntframe23a(padapter, pmgntframe);
kfree(pmlmepriv->assoc_req);
pmlmepriv->assoc_req = kmalloc(pattrib->pktlen, GFP_ATOMIC);
if (pmlmepriv->assoc_req) {
- memcpy(pmlmepriv->assoc_req, pwlanhdr,
- pattrib->pktlen);
+ memcpy(pmlmepriv->assoc_req, pwlanhdr, pattrib->pktlen);
pmlmepriv->assoc_req_len = pattrib->pktlen;
}
} else
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv;
struct mlme_ext_priv *pmlmeext;
struct mlme_ext_info *pmlmeinfo;
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl, *qc;
+ __le16 *fctrl;
+ u16 *qc;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
int ret = _FAIL;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif /* CONFIG_8723AU_P2P */
/* DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
-#ifdef CONFIG_8723AU_P2P
- if (!(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) &&
- (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
- mod_timer(&pwdinfo->reset_ch_sitesurvey,
- jiffies + msecs_to_jiffies(10));
- }
-#endif /* CONFIG_8723AU_P2P */
-
if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
goto exit;
struct pkt_attrib *pattrib;
unsigned char *pframe;
struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
u8 category, action;
dump_mgntframe23a(padapter, pmgntframe);
}
-void issue_action_BA23a(struct rtw_adapter *padapter, unsigned char *raddr,
+void issue_action_BA23a(struct rtw_adapter *padapter,
+ const unsigned char *raddr,
unsigned char action, unsigned short status)
{
u8 category = WLAN_CATEGORY_BACK;
struct pkt_attrib *pattrib;
u8 *pframe;
struct ieee80211_hdr *pwlanhdr;
- u16 *fctrl;
+ __le16 *fctrl;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
{
struct list_head *plist, *phead, *ptmp;
unsigned char category, action;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct wlan_network *pnetwork = NULL;
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ u8 *pframe;
+ struct ieee80211_hdr *pwlanhdr;
+ __le16 *fctrl;
+ struct wlan_network *pnetwork;
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 rtw_queue *queue = &pmlmepriv->scanned_queue;
+ struct rtw_queue *queue = &pmlmepriv->scanned_queue;
u8 InfoContent[16] = {0};
u8 ICS[8][15];
+ int i;
- if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0))
+ if (pmlmepriv->num_FortyMHzIntolerant == 0 ||
+ pmlmepriv->num_sta_no_ht == 0)
return;
- if (true == pmlmeinfo->bwmode_updated)
+ if (pmlmeinfo->bwmode_updated)
return;
DBG_8723A("%s\n", __func__);
category = WLAN_CATEGORY_PUBLIC;
action = ACT_PUBLIC_BSSCOEXIST;
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- {
+ pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
+ if (!pmgntframe)
return;
- }
/* update attribute */
pattrib = &pmgntframe->attrib;
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
+ pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
pwlanhdr = (struct ieee80211_hdr *)pframe;
fctrl = &pwlanhdr->frame_control;
pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
- /* */
- if (pmlmepriv->num_FortyMHzIntolerant>0)
- {
- u8 iedata = 0;
-
- iedata |= BIT(2);/* 20 MHz BSS Width Request */
-
- pframe = rtw_set_ie23a(pframe, EID_BSSCoexistence, 1, &iedata, &pattrib->pktlen);
+ if (pmlmepriv->num_FortyMHzIntolerant > 0) {
+ u8 iedata = BIT(2);/* 20 MHz BSS Width Request */
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_BSS_COEX_2040, 1,
+ &iedata, &pattrib->pktlen);
}
- /* */
- memset(ICS, 0, sizeof(ICS));
- if (pmlmepriv->num_sta_no_ht>0)
- {
- int i;
+ if (pmlmepriv->num_sta_no_ht <= 0)
+ goto out;
- spin_lock_bh(&pmlmepriv->scanned_queue.lock);
+ memset(ICS, 0, sizeof(ICS));
- phead = get_list_head(queue);
- plist = phead->next;
+ spin_lock_bh(&pmlmepriv->scanned_queue.lock);
- list_for_each_safe(plist, ptmp, phead) {
- int len;
- u8 *p;
- struct wlan_bssid_ex *pbss_network;
+ phead = get_list_head(queue);
+ plist = phead->next;
- pnetwork = container_of(plist, struct wlan_network,
- list);
+ list_for_each_safe(plist, ptmp, phead) {
+ const u8 *p;
+ struct wlan_bssid_ex *pbss_network;
- pbss_network = &pnetwork->network;
+ pnetwork = container_of(plist, struct wlan_network, list);
- p = rtw_get_ie23a(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
- if ((p == NULL) || (len == 0))/* non-HT */
- {
- if ((pbss_network->Configuration.DSConfig<= 0) || (pbss_network->Configuration.DSConfig>14))
- continue;
+ pbss_network = &pnetwork->network;
- ICS[0][pbss_network->Configuration.DSConfig]= 1;
+ p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
+ pbss_network->IEs + _FIXED_IE_LENGTH_,
+ pbss_network->IELength -_FIXED_IE_LENGTH_);
+ if (!p || !p[1]) { /* non-HT */
+ if (pbss_network->Configuration.DSConfig <= 0 ||
+ pbss_network->Configuration.DSConfig > 14)
+ continue;
- if (ICS[0][0] == 0)
- ICS[0][0] = 1;
- }
+ ICS[0][pbss_network->Configuration.DSConfig] = 1;
+ if (ICS[0][0] == 0)
+ ICS[0][0] = 1;
}
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
+ }
- for (i = 0;i<8;i++)
- {
- if (ICS[i][0] == 1)
- {
- int j, k = 0;
+ spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
- InfoContent[k] = i;
- /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
- k++;
+ for (i = 0; i < 8;i++) {
+ if (ICS[i][0] == 1) {
+ int j, k = 0;
- for (j = 1;j<= 14;j++)
- {
- if (ICS[i][j]== 1)
- {
- if (k<16)
- {
- InfoContent[k] = j; /* channel number */
- /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
- k++;
- }
+ InfoContent[k] = i;
+ /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
+ k++;
+
+ for (j = 1; j <= 14; j++) {
+ if (ICS[i][j] == 1) {
+ if (k < 16) {
+ /* channel number */
+ InfoContent[k] = j;
+ k++;
}
}
-
- pframe = rtw_set_ie23a(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &pattrib->pktlen);
-
}
+ pframe = rtw_set_ie23a(pframe,
+ EID_BSSIntolerantChlReport, k,
+ InfoContent, &pattrib->pktlen);
}
-
}
+out:
pattrib->last_txcmdsz = pattrib->pktlen;
dump_mgntframe23a(padapter, pmgntframe);
unsigned int send_beacon23a(struct rtw_adapter *padapter)
{
- u8 bxmitok = false;
+ bool bxmitok;
int issue = 0;
int poll = 0;
unsigned long start = jiffies;
unsigned int passing_time;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BCN_VALID, NULL);
+ rtl8723a_bcn_valid(padapter);
do {
issue_beacon23a(padapter, 100);
issue++;
do {
yield();
- rtw23a_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
+ bxmitok = rtl8723a_get_bcn_valid(padapter);
poll++;
- } while ((poll%10)!= 0 && false == bxmitok &&
+ } while ((poll % 10) != 0 && bxmitok == false &&
!padapter->bSurpriseRemoved &&
!padapter->bDriverStopped);
void site_survey23a(struct rtw_adapter *padapter)
{
- unsigned char survey_channel = 0, val8;
+ 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;
- u32 initialgain = 0;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) ||
- (pwdinfo->p2p_info.scan_op_ch_only)) {
- if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
- survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
- else
- survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
- ScanType = SCAN_ACTIVE;
- } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
- /* The driver is in the find phase, it should go through the social channel. */
- int ch_set_idx;
- survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx];
- ch_set_idx = rtw_ch_set_search_ch23a(pmlmeext->channel_set, survey_channel);
- if (ch_set_idx >= 0)
- ScanType = pmlmeext->channel_set[ch_set_idx].ScanType;
- else
- ScanType = SCAN_ACTIVE;
- } else
-#endif /* CONFIG_8723AU_P2P */
- {
- 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;
-}
+ 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_survey23a */
- /* rtw23a_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
- /* val8 |= 0x0f; */
- /* rtw_hal_set_hwreg23a(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
if (pmlmeext->sitesurvey_res.channel_idx == 0)
set_channel_bwmode23a(padapter, survey_channel,
HAL_PRIME_CHNL_OFFSET_DONT_CARE,
if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
{
-#ifdef CONFIG_8723AU_P2P
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
- rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
- )
- {
- issue23a_probereq_p2p(padapter, NULL);
- issue23a_probereq_p2p(padapter, NULL);
- issue23a_probereq_p2p(padapter, NULL);
- }
- else
-#endif /* CONFIG_8723AU_P2P */
- {
- 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_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
- /* msleep(SURVEY_TO>>1); */
- issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
- }
- }
-
- if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
+ 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_probereq23a(padapter, NULL, NULL);
+ issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
/* msleep(SURVEY_TO>>1); */
- issue_probereq23a(padapter, NULL, NULL);
+ issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
}
}
+
+ if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
+ /* todo: to issue two probe req??? */
+ issue_probereq23a(padapter, NULL, NULL);
+ /* msleep(SURVEY_TO>>1); */
+ issue_probereq23a(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 */
-#ifdef CONFIG_8723AU_P2P
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
- {
- if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) || (pwdinfo->p2p_info.scan_op_ch_only))
- {
- /* Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT. */
- /* This will let the following flow to run the scanning end. */
- rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
- }
- }
-
- if (rtw_p2p_findphase_ex_is_needed(pwdinfo))
- {
- /* Set the P2P State to the listen state of find phase and set the current channel to the listen channel */
- set_channel_bwmode23a(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
- pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
-
- initialgain = 0xff; /* restore RX GAIN */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
- /* turn on dynamic functions */
- Restore_DM_Func_Flag23a(padapter);
- /* Switch_DM_Func23a(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, true); */
-
- mod_timer(&pwdinfo->find_phase_timer, jiffies +
- msecs_to_jiffies(pwdinfo->listen_dwell * 100));
- } else
-#endif /* CONFIG_8723AU_P2P */
- {
-#ifdef CONFIG_8723AU_P2P
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
- rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
-#endif /* CONFIG_8723AU_P2P */
-
- 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);
+ set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
+ pmlmeext->cur_ch_offset,
+ pmlmeext->cur_bwmode);
- /* flush 4-AC Queue after site_survey23a */
- /* val8 = 0; */
- /* rtw_hal_set_hwreg23a(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
+ /* flush 4-AC Queue after site_survey23a */
+ /* val8 = 0; */
- /* config MSR */
- Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
-
- initialgain = 0xff; /* restore RX GAIN */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
- /* turn on dynamic functions */
- Restore_DM_Func_Flag23a(padapter);
- /* Switch_DM_Func23a(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */
-
- if (is_client_associated_to_ap23a(padapter) == true)
- {
- issue_nulldata23a(padapter, NULL, 0, 3, 500);
+ /* config MSR */
+ Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
- }
+ /* restore RX GAIN */
+ rtl8723a_set_initial_gain(padapter, 0xff);
+ /* turn on dynamic functions */
+ rtl8723a_odm_support_ability_restore(padapter);
- val8 = 0; /* survey done */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+ if (is_client_associated_to_ap23a(padapter) == true)
+ issue_nulldata23a(padapter, NULL, 0, 3, 500);
- report_surveydone_event23a(padapter);
+ rtl8723a_mlme_sitesurvey(padapter, 0);
- pmlmeext->chan_scan_time = SURVEY_TO;
- pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
+ report_surveydone_event23a(padapter);
- issue_action_BSSCoexistPacket(padapter);
- issue_action_BSSCoexistPacket(padapter);
- issue_action_BSSCoexistPacket(padapter);
+ pmlmeext->chan_scan_time = SURVEY_TO;
+ pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
- }
+ issue_action_BSSCoexistPacket(padapter);
+ issue_action_BSSCoexistPacket(padapter);
+ issue_action_BSSCoexistPacket(padapter);
}
return;
}
/* collect bss info from Beacon and Probe request/response frames. */
-u8 collect_bss_info23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame, struct wlan_bssid_ex *bssid)
+u8 collect_bss_info23a(struct rtw_adapter *padapter,
+ struct recv_frame *precv_frame,
+ struct wlan_bssid_ex *bssid)
{
- int i;
- u32 len;
- u8 *p;
- u16 val16;
+ int i;
+ const u8 *p;
struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u8 *pframe = skb->data;
- u32 packet_len = skb->len;
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
+ unsigned int length;
u8 ie_offset;
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ u16 capab_info;
- len = packet_len - sizeof(struct ieee80211_hdr_3addr);
+ length = skb->len - sizeof(struct ieee80211_hdr_3addr);
- if (len > MAX_IE_SZ)
- {
+ if (length > MAX_IE_SZ) {
/* DBG_8723A("IE too long for survey event\n"); */
return _FAIL;
}
memset(bssid, 0, sizeof(struct wlan_bssid_ex));
- if (ieee80211_is_beacon(hdr->frame_control)) {
+ if (ieee80211_is_beacon(mgmt->frame_control)) {
bssid->reserved = 1;
- ie_offset = _BEACON_IE_OFFSET_;
+ ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
+ capab_info = mgmt->u.beacon.capab_info;
+ } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
+ ie_offset = offsetof(struct ieee80211_mgmt,
+ u.probe_req.variable);
+ bssid->reserved = 2;
+ capab_info = 0;
+ } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
+ ie_offset = offsetof(struct ieee80211_mgmt,
+ u.probe_resp.variable);
+ bssid->reserved = 3;
+ capab_info = mgmt->u.probe_resp.capab_info;
} else {
- /* FIXME : more type */
- if (ieee80211_is_probe_req(hdr->frame_control)) {
- ie_offset = _PROBEREQ_IE_OFFSET_;
- bssid->reserved = 2;
- } else if (ieee80211_is_probe_resp(hdr->frame_control)) {
- ie_offset = _PROBERSP_IE_OFFSET_;
- bssid->reserved = 3;
- } else {
- bssid->reserved = 0;
- ie_offset = _FIXED_IE_LENGTH_;
- }
+ bssid->reserved = 0;
+ ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
+ capab_info = mgmt->u.beacon.capab_info;
}
+ ie_offset -= offsetof(struct ieee80211_mgmt, u);
- bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
+ bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + length;
/* below is to copy the information element */
- bssid->IELength = len;
- memcpy(bssid->IEs, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->IELength);
+ bssid->IELength = length;
+ memcpy(bssid->IEs, &mgmt->u, bssid->IELength);
/* get the signal strength */
- bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower; /* in dBM.raw data */
- bssid->PhyInfo.SignalQuality = precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
- bssid->PhyInfo.SignalStrength = precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
+ /* in dBM.raw data */
+ bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower;
+ bssid->PhyInfo.SignalQuality =
+ precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
+ bssid->PhyInfo.SignalStrength =
+ precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
/* checking SSID */
- if ((p = rtw_get_ie23a(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset)) == NULL)
- {
+ p = cfg80211_find_ie(WLAN_EID_SSID, bssid->IEs + ie_offset,
+ bssid->IELength - ie_offset);
+
+ if (!p) {
DBG_8723A("marc: cannot find SSID for survey event\n");
return _FAIL;
}
- if (*(p + 1)) {
- if (len > IEEE80211_MAX_SSID_LEN) {
- DBG_8723A("%s()-%d: IE too long (%d) for survey "
- "event\n", __func__, __LINE__, len);
- return _FAIL;
- }
- memcpy(bssid->Ssid.ssid, (p + 2), *(p + 1));
- bssid->Ssid.ssid_len = *(p + 1);
- } else {
- bssid->Ssid.ssid_len = 0;
+ if (p[1] > IEEE80211_MAX_SSID_LEN) {
+ DBG_8723A("%s()-%d: IE too long (%d) for survey "
+ "event\n", __func__, __LINE__, p[1]);
+ return _FAIL;
}
+ memcpy(bssid->Ssid.ssid, p + 2, p[1]);
+ bssid->Ssid.ssid_len = p[1];
memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
/* checking rate info... */
i = 0;
- p = rtw_get_ie23a(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
- if (p != NULL)
- {
- if (len > NDIS_802_11_LENGTH_RATES_EX)
- {
- DBG_8723A("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
+ p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, bssid->IEs + ie_offset,
+ bssid->IELength - ie_offset);
+ 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]);
return _FAIL;
}
- memcpy(bssid->SupportedRates, (p + 2), len);
- i = len;
+ memcpy(bssid->SupportedRates, p + 2, p[1]);
+ i = p[1];
}
- p = rtw_get_ie23a(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
- if (p != NULL)
- {
- if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
- {
- DBG_8723A("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
+ p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, bssid->IEs + ie_offset,
+ bssid->IELength - ie_offset);
+ 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]);
return _FAIL;
}
- memcpy(bssid->SupportedRates + i, (p + 2), len);
+ memcpy(bssid->SupportedRates + i, p + 2, p[1]);
}
- /* todo: */
- {
- bssid->NetworkTypeInUse = Ndis802_11OFDM24;
- }
+ bssid->NetworkTypeInUse = Ndis802_11OFDM24;
if (bssid->IELength < 12)
return _FAIL;
/* Checking for DSConfig */
- p = rtw_get_ie23a(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
+ p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bssid->IEs + ie_offset,
+ bssid->IELength - ie_offset);
bssid->Configuration.DSConfig = 0;
bssid->Configuration.Length = 0;
- if (p)
- {
- bssid->Configuration.DSConfig = *(p + 2);
- }
- else
- {/* In 5G, some ap do not have DSSET IE */
+ if (p) {
+ bssid->Configuration.DSConfig = p[2];
+ } else {/* In 5G, some ap do not have DSSET IE */
/* checking HT info for channel */
- p = rtw_get_ie23a(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
- if (p)
- {
- struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
- bssid->Configuration.DSConfig = HT_info->primary_channel;
- }
- else
- { /* use current channel */
- bssid->Configuration.DSConfig = rtw_get_oper_ch23a(padapter);
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
+ bssid->IEs + ie_offset,
+ bssid->IELength - ie_offset);
+ if (p) {
+ struct HT_info_element *HT_info =
+ (struct HT_info_element *)(p + 2);
+ bssid->Configuration.DSConfig =
+ HT_info->primary_channel;
+ } else { /* use current channel */
+ bssid->Configuration.DSConfig =
+ rtw_get_oper_ch23a(padapter);
}
}
- if (ieee80211_is_probe_req(hdr->frame_control)) {
+ if (ieee80211_is_probe_req(mgmt->frame_control)) {
/* FIXME */
bssid->InfrastructureMode = Ndis802_11Infrastructure;
- ether_addr_copy(bssid->MacAddress, hdr->addr2);
+ ether_addr_copy(bssid->MacAddress, mgmt->sa);
bssid->Privacy = 1;
return _SUCCESS;
}
- memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval23a_from_ie(bssid->IEs), 2);
- bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
+ memcpy(&bssid->Configuration.BeaconPeriod,
+ rtw_get_beacon_interval23a_from_ie(bssid->IEs), 2);
+ bssid->Configuration.BeaconPeriod =
+ le32_to_cpu(bssid->Configuration.BeaconPeriod);
- val16 = rtw_get_capability23a(bssid);
-
- if (val16 & BIT(0)) {
+ if (capab_info & BIT(0)) {
bssid->InfrastructureMode = Ndis802_11Infrastructure;
- ether_addr_copy(bssid->MacAddress, hdr->addr2);
+ ether_addr_copy(bssid->MacAddress, mgmt->sa);
} else {
bssid->InfrastructureMode = Ndis802_11IBSS;
- ether_addr_copy(bssid->MacAddress, hdr->addr3);
+ ether_addr_copy(bssid->MacAddress, mgmt->bssid);
}
- if (val16 & BIT(4))
+ if (capab_info & BIT(4))
bssid->Privacy = 1;
else
bssid->Privacy = 0;
bssid->Configuration.ATIMWindow = 0;
/* 20/40 BSS Coexistence check */
- if ((pregistrypriv->wifi_spec == 1) && (false == pmlmeinfo->bwmode_updated))
- {
+ if (pregistrypriv->wifi_spec == 1 &&
+ pmlmeinfo->bwmode_updated == false) {
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- p = rtw_get_ie23a(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);
+ p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
+ bssid->IEs + ie_offset,
+ bssid->IELength - ie_offset);
+ if (p && p[1] > 0) {
+ struct HT_caps_element *pHT_caps;
+ pHT_caps = (struct HT_caps_element *)(p + 2);
if (pHT_caps->u.HT_cap_element.HT_caps_info & BIT(14))
pmlmepriv->num_FortyMHzIntolerant++;
} else
- {
pmlmepriv->num_sta_no_ht++;
- }
}
void start_create_ibss23a(struct rtw_adapter* padapter)
{
unsigned short caps;
- u8 val8;
- u8 join_type;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
/* udpate capability */
caps = rtw_get_capability23a(pnetwork);
update_capinfo23a(padapter, caps);
- if (caps&cap_IBSS)/* adhoc master */
- {
- val8 = 0xcf;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
+ if (caps&cap_IBSS) { /* adhoc master */
+ rtl8723a_set_sec_cfg(padapter, 0xcf);
/* switch channel */
/* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
}
else
{
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
- join_type = 0;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
+ 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;
Set_MSR23a(padapter, WIFI_FW_STATION_STATE);
- val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
+ val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ?
+ 0xcc: 0xcf;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
+ rtl8723a_set_sec_cfg(padapter, val8);
/* switch channel */
/* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout));
pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
}
- else if (caps&cap_IBSS) /* adhoc client */
- {
+ else if (caps&cap_IBSS) { /* adhoc client */
Set_MSR23a(padapter, WIFI_FW_ADHOC_STATE);
- val8 = 0xcf;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
+ rtl8723a_set_sec_cfg(padapter, 0xcf);
/* switch channel */
set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
return _SUCCESS;
}
-static void process_80211d(struct rtw_adapter *padapter, struct wlan_bssid_ex *bssid)
+static void process_80211d(struct rtw_adapter *padapter,
+ struct wlan_bssid_ex *bssid)
{
struct registry_priv *pregistrypriv;
struct mlme_ext_priv *pmlmeext;
/* Adjust channel plan by AP Country IE */
if (pregistrypriv->enable80211d &&
- (!pmlmeext->update_channel_plan_by_ap_done))
- {
- u8 *ie, *p;
- u32 len;
+ !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 noc; /* number of channel */
u8 j, k;
- ie = rtw_get_ie23a(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
- if (!ie) return;
- if (len < 6) return;
+ ie = cfg80211_find_ie(WLAN_EID_COUNTRY,
+ bssid->IEs + _FIXED_IE_LENGTH_,
+ bssid->IELength - _FIXED_IE_LENGTH_);
+ if (!ie || ie[1] < IEEE80211_COUNTRY_IE_MIN_LEN)
+ return;
+ p = ie + 2;
+ ie += ie[1];
ie += 2;
- p = ie;
- ie += len;
- memset(country, 0, 4);
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));
+ ("%s: 802.11d country =%s\n", __func__, country));
i = 0;
- while ((ie - p) >= 3)
- {
+ 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 */
+ 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;
}
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))
+ 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))
+ 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];
+ 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;
+ } 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;
+ } 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;
+ 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)) {
+ 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++;
}
} 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;
+ 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)) {
+ 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))
+ if (i == MAX_CHANNEL_NUM ||
+ chplan_sta[i].ChannelNum == 0)
break;
- if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
+ 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];
+ 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 = chplan_sta[i].ScanType; */
+ } 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];
+ } 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;
+ 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)) {
+ 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++;
}
} 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;
+ 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++;
channel = bssid->Configuration.DSConfig;
chplan_new = pmlmeext->channel_set;
i = 0;
- while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
- if (chplan_new[i].ChannelNum == channel)
- {
+ 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 */
+ /* 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));
+ ("%s: change channel %d scan type "
+ "from passive to active\n",
+ __func__, channel));
}
break;
}
return;
}
- INIT_LIST_HEAD(&pcmd_obj->list);
-
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
pcmd_obj->cmdsz = cmdsz;
pcmd_obj->parmbuf = pevtcmd;
return;
}
- INIT_LIST_HEAD(&pcmd_obj->list);
-
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
pcmd_obj->cmdsz = cmdsz;
pcmd_obj->parmbuf = pevtcmd;
return;
}
- INIT_LIST_HEAD(&pcmd_obj->list);
-
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
pcmd_obj->cmdsz = cmdsz;
pcmd_obj->parmbuf = pevtcmd;
return;
}
- INIT_LIST_HEAD(&pcmd_obj->list);
-
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
pcmd_obj->cmdsz = cmdsz;
pcmd_obj->parmbuf = pevtcmd;
return;
}
- INIT_LIST_HEAD(&pcmd_obj->list);
-
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
pcmd_obj->cmdsz = cmdsz;
pcmd_obj->parmbuf = pevtcmd;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
struct sta_priv *pstapriv = &padapter->stapriv;
- u8 join_type;
- u16 media_status;
- if (join_res < 0)
- {
- join_type = 1;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID, null_addr);
+ 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);
+ update_tx_basic_rate23a(padapter,
+ padapter->registrypriv.wireless_mode);
goto exit_mlmeext_joinbss_event_callback23a;
}
}
/* turn on dynamic functions */
- Switch_DM_Func23a(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
+ rtl8723a_odm_support_ability_set(padapter, DYNAMIC_ALL_FUNC_ENABLE);
/* update IOT-releated issue */
update_IOT_info23a(padapter);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
+ HalSetBrateCfg23a(padapter, cur_network->SupportedRates);
/* BCN interval */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
+ rtl8723a_set_beacon_interval(padapter, pmlmeinfo->bcn_interval);
/* udpate capability */
update_capinfo23a(padapter, pmlmeinfo->capability);
/* set per sta rate after updating HT cap. */
set_sta_rate23a(padapter, psta);
-
- media_status = (psta->mac_id<<8)|1; /* MACID|OPMODE: 1 means connect */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
}
- join_type = 2;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
+ hw_var_set_mlme_join(padapter, 2);
- if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
- {
+ if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
/* correcting TSF */
- correct_TSF23a(padapter, pmlmeext);
+ rtw_correct_TSF(padapter);
/* set_link_timer(pmlmeext, DISCONNECT_TO); */
}
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- u8 join_type;
DBG_8723A("%s\n", __func__);
}
else/* adhoc client */
{
- /* update TSF Value */
- /* update_TSF23a(pmlmeext, pframe, len); */
-
/* correcting TSF */
- correct_TSF23a(padapter, pmlmeext);
+ rtw_correct_TSF(padapter);
/* start beacon */
if (send_beacon23a(padapter) == _FAIL)
}
- join_type = 2;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
+ hw_var_set_mlme_join(padapter, 2);
}
pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
{
/* set_opmode_cmd(padapter, infra_client_with_mlme); */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_DISCONNECT, NULL);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID, null_addr);
+ 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);
}
}
-/****************************************************************************
-
-Following are the functions for the timer handlers
-
-*****************************************************************************/
-void linked23a_rx_sig_stren_disp(struct rtw_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- u8 mac_id;
- int UndecoratedSmoothedPWDB;
- if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
- mac_id = 0;
- else if ((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
- mac_id = 2;
-
- rtw_hal_get_def_var23a(padapter, HW_DEF_RA_INFO_DUMP,&mac_id);
-
- rtw_hal_get_def_var23a(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
- DBG_8723A("UndecoratedSmoothedPWDB:%d\n", UndecoratedSmoothedPWDB);
-}
-
static u8 chk_ap_is_alive(struct rtw_adapter *padapter, struct sta_info *psta)
{
u8 ret = false;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct sta_priv *pstapriv = &padapter->stapriv;
- if (padapter->bRxRSSIDisplay)
- linked23a_rx_sig_stren_disp(padapter);
-
rtw_hal_sreset_linked_status_check23a(padapter);
if (is_client_associated_to_ap23a(padapter))
if ((psta = rtw_get_stainfo23a(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
{
bool is_p2p_enable = false;
-#ifdef CONFIG_8723AU_P2P
- is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
-#endif
if (chk_ap_is_alive(padapter, psta) == false)
rx_chk = _FAIL;
struct sitesurvey_parm *psurveyPara;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif
/* 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)
- {
-#ifdef CONFIG_8723AU_P2P
- if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
- {
- rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
- pmlmeext->sitesurvey_res.channel_idx = 3;
- DBG_8723A("%s idx:%d, cnt:%u\n", __func__,
- pmlmeext->sitesurvey_res.channel_idx,
- pwdinfo->find_phase_state_exchange_cnt);
- } else
- #endif
- {
- pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
- DBG_8723A("%s idx:%d\n", __func__,
- 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 */
}
(unsigned long)padapter);
}
-u8 NULL_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
+u8 NULL_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
return H2C_SUCCESS;
}
-u8 setopmode_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
+u8 setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
u8 type;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
+ const struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
- if (psetop->mode == Ndis802_11APMode)
- {
+ if (psetop->mode == Ndis802_11APMode) {
pmlmeinfo->state = WIFI_FW_AP_STATE;
type = _HW_STATE_AP_;
- }
- else if (psetop->mode == Ndis802_11Infrastructure)
- {
+ } else if (psetop->mode == Ndis802_11Infrastructure) {
pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */
pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
type = _HW_STATE_STATION_;
- }
- else if (psetop->mode == Ndis802_11IBSS)
- {
+ } else if (psetop->mode == Ndis802_11IBSS)
type = _HW_STATE_ADHOC_;
- }
else
- {
type = _HW_STATE_NOLINK_;
- }
- rtw_hal_set_hwreg23a(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
+ hw_var_set_opmode(padapter, type);
/* Set_NETYPE0_MSR(padapter, type); */
return H2C_SUCCESS;
}
-u8 createbss_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
+u8 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;
- struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
+ const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
/* u32 initialgain; */
if (pparm->InfrastructureMode == Ndis802_11APMode) {
pmlmeinfo->candidate_tid_bitmap = 0;
/* disable dynamic functions, such as high power, DIG */
- Save_DM_Func_Flag23a(padapter);
- Switch_DM_Func23a(padapter, DYNAMIC_FUNC_DISABLE, false);
+ rtl8723a_odm_support_ability_backup(padapter);
- /* config the initial gain under linking, need to write the BB registers */
- /* initialgain = 0x1E; */
- /* rtw_hal_set_hwreg23a(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
+ rtl8723a_odm_support_ability_clr(padapter,
+ DYNAMIC_FUNC_DISABLE);
/* cancel link timer */
del_timer_sync(&pmlmeext->link_timer);
return H2C_SUCCESS;
}
-u8 join_cmd_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
+u8 join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
- u8 join_type;
struct ndis_802_11_var_ies * pIE;
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;
- struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
+ const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
struct HT_info_element *pht_info;
u32 i;
/* u32 initialgain; */
/* Set_MSR23a(padapter, _HW_STATE_NOLINK_); */
Set_MSR23a(padapter, _HW_STATE_STATION_);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_DISCONNECT, NULL);
+ hw_var_set_mlme_disconnect(padapter);
}
rtw_joinbss_reset23a(padapter);
switch (pIE->ElementID)
{
- case _VENDOR_SPECIFIC_IE_:/* Get WMM IE. */
+ case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
if (!memcmp(pIE->data, WMM_OUI23A, 4))
pmlmeinfo->WMM_enable = 1;
break;
- case _HT_CAPABILITY_IE_: /* Get HT Cap IE. */
+ case WLAN_EID_HT_CAPABILITY: /* Get HT Cap IE. */
pmlmeinfo->HT_caps_enable = 1;
break;
- case _HT_EXTRA_INFO_IE_: /* Get HT Info IE. */
+ 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
i += (pIE->Length + 2);
}
- /* disable dynamic functions, such as high power, DIG */
- /* Switch_DM_Func23a(padapter, DYNAMIC_FUNC_DISABLE, false); */
-
- /* config the initial gain under linking, need to write the BB
- registers */
- /* initialgain = 0x1E; */
- /* rtw_hal_set_hwreg23a(padapter, HW_VAR_INITIAL_GAIN,
- (u8 *)(&initialgain)); */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID,
- pmlmeinfo->network.MacAddress);
- join_type = 0;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
+ hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
+ hw_var_set_mlme_join(padapter, 0);
/* cancel link timer */
del_timer_sync(&pmlmeext->link_timer);
return H2C_SUCCESS;
}
-u8 disconnect_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
+u8 disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
- struct disconnect_parm *param = (struct disconnect_parm *)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;
- u8 val8;
if (is_client_associated_to_ap23a(padapter))
{
/* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_DISCONNECT, NULL);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID, null_addr);
+ 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) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
- {
- /* Stop BCN */
- val8 = 0;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
- }
+ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
+ ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
+ rtl8723a_set_bcn_func(padapter, 0); /* Stop BCN */
/* set MSR to no link state -> infra. mode */
Set_MSR23a(padapter, _HW_STATE_STATION_);
return H2C_SUCCESS;
}
-static int rtw_scan_ch_decision(struct rtw_adapter *padapter, struct rtw_ieee80211_channel *out,
- u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
+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;
return j;
}
-u8 sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
+u8 sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
+ const struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
u8 bdelayscan = false;
- u8 val8;
u32 initialgain;
u32 i;
if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
- /* for first time sitesurvey_cmd */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_CHECK_TXBUF, NULL);
-
pmlmeext->sitesurvey_res.state = SCAN_START;
pmlmeext->sitesurvey_res.bss_cnt = 0;
pmlmeext->sitesurvey_res.channel_idx = 0;
if ((pmlmeext->sitesurvey_res.state == SCAN_START) ||
(pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
/* disable dynamic functions, such as high power, DIG */
- Save_DM_Func_Flag23a(padapter);
- Switch_DM_Func23a(padapter, DYNAMIC_FUNC_DISABLE, false);
+ rtl8723a_odm_support_ability_backup(padapter);
+ rtl8723a_odm_support_ability_clr(padapter,
+ DYNAMIC_FUNC_DISABLE);
/* config the initial gain under scaning, need to
write the BB registers */
- if ((wdev_to_priv(padapter->rtw_wdev))->p2p_enabled == true) {
+ if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == true)
initialgain = 0x30;
- } else
+ else
initialgain = 0x1E;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_INITIAL_GAIN,
- (u8 *)(&initialgain));
+ rtl8723a_set_initial_gain(padapter, initialgain);
/* set MSR to no link state */
Set_MSR23a(padapter, _HW_STATE_NOLINK_);
- val8 = 1; /* under site survey */
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_SITESURVEY,
- (u8 *)(&val8));
+ rtl8723a_mlme_sitesurvey(padapter, 1);
pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
}
return H2C_SUCCESS;
}
-u8 setauth_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
+u8 setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
- struct setauth_parm *pparm = (struct setauth_parm *)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;
return H2C_SUCCESS;
}
-u8 setkey_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
+u8 setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
unsigned short ctrl;
- struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
+ 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};
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);
- write_cam23a(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
+ rtl8723a_cam_write(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
/* allow multicast packets to driver */
- padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_ON_RCR_AM, null_addr);
+ rtl8723a_on_rcr_am(padapter);
return H2C_SUCCESS;
}
-u8 set_stakey_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
+u8 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;
- struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
+ const struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
/* cam_entry: */
/* 0~3 for default key */
pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
pparm->addr[5], cam_id);
- write_cam23a(padapter, cam_id, ctrl, pparm->addr, pparm->key);
+ rtl8723a_cam_write(padapter, cam_id, ctrl,
+ pparm->addr, pparm->key);
return H2C_SUCCESS_RSP;
ctrl = BIT(15) | ((pparm->algorithm) << 2);
- write_cam23a(padapter, cam_id, ctrl, pparm->addr, pparm->key);
+ rtl8723a_cam_write(padapter, cam_id, ctrl, pparm->addr, pparm->key);
pmlmeinfo->enc_algo = pparm->algorithm;
return H2C_SUCCESS;
}
-u8 add_ba_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
+u8 add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
- struct addBaReq_parm *pparm = (struct addBaReq_parm *)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;
return res;
}
-u8 mlme_evt_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
+u8 mlme_evt_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
u8 evt_code, evt_seq;
u16 evt_sz;
- uint *peventbuf;
+ const uint *peventbuf;
void (*event_callback)(struct rtw_adapter *dev, u8 *pbuf);
struct evt_priv *pevt_priv = &padapter->evtpriv;
return H2C_SUCCESS;
}
-u8 h2c_msg_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
+u8 h2c_msg_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
if (!pbuf)
return H2C_PARAMETERS_ERROR;
return H2C_SUCCESS;
}
-u8 tx_beacon_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
+u8 tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
if (send_beacon23a(padapter) == _FAIL)
{
return H2C_SUCCESS;
}
-u8 set_ch_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
+u8 set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
- struct set_ch_parm *set_ch_parm;
+ const struct set_ch_parm *set_ch_parm;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
if (!pbuf)
return H2C_SUCCESS;
}
-u8 set_chplan_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
+u8 set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
- struct SetChannelPlan_param *setChannelPlan_param;
+ const struct SetChannelPlan_param *setChannelPlan_param;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
if (!pbuf)
return H2C_SUCCESS;
}
-u8 led_blink_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
+u8 led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
struct LedBlink_param *ledBlink_param;
return H2C_SUCCESS;
}
-u8 set_csa_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
+u8 set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
return H2C_REJECTED;
}
/* TDLS_CKALV_PH1 : check alive timer phase1 */
/* TDLS_CKALV_PH2 : check alive timer phase2 */
/* TDLS_FREE_STA : free tdls sta */
-u8 tdls_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
+u8 tdls_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
return H2C_REJECTED;
}
+++ /dev/null
-/******************************************************************************
- *
- * 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_P2P_C_
-
-#include <drv_types.h>
-#include <rtw_p2p.h>
-#include <wifi.h>
-
-#ifdef CONFIG_8723AU_P2P
-
-static int rtw_p2p_is_channel_list_ok(u8 desired_ch, u8* ch_list, u8 ch_cnt)
-{
- int found = 0, i = 0;
-
- for (i = 0; i < ch_cnt; i++)
- {
- if (ch_list[ i ] == desired_ch)
- {
- found = 1;
- break;
- }
- }
- return found;
-}
-
-static int is_any_client_associated(struct rtw_adapter *padapter)
-{
- return padapter->stapriv.asoc_list_cnt ? true : false;
-}
-
-static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- struct list_head *phead, *plist;
- u32 len = 0;
- u16 attr_len = 0;
- u8 tmplen, *pdata_attr, *pstart, *pcur;
- struct sta_info *psta;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- DBG_8723A("%s\n", __func__);
-
- pdata_attr = kzalloc(MAX_P2P_IE_LEN, GFP_ATOMIC);
-
- pstart = pdata_attr;
- pcur = pdata_attr;
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- phead = &pstapriv->asoc_list;
-
- list_for_each(plist, phead) {
- psta = container_of(plist, struct sta_info, asoc_list);
-
- if (psta->is_p2p_device)
- {
- tmplen = 0;
-
- pcur++;
-
- /* P2P device address */
- memcpy(pcur, psta->dev_addr, ETH_ALEN);
- pcur += ETH_ALEN;
-
- /* P2P interface address */
- memcpy(pcur, psta->hwaddr, ETH_ALEN);
- pcur += ETH_ALEN;
-
- *pcur = psta->dev_cap;
- pcur++;
-
- /* u16*)(pcur) = cpu_to_be16(psta->config_methods); */
- put_unaligned_be16(psta->config_methods, pcur);
- pcur += 2;
-
- memcpy(pcur, psta->primary_dev_type, 8);
- pcur += 8;
-
- *pcur = psta->num_of_secdev_type;
- pcur++;
-
- memcpy(pcur, psta->secdev_types_list, psta->num_of_secdev_type*8);
- pcur += psta->num_of_secdev_type*8;
-
- if (psta->dev_name_len>0)
- {
- /* u16*)(pcur) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
- put_unaligned_be16(WPS_ATTR_DEVICE_NAME, pcur);
- pcur += 2;
-
- /* u16*)(pcur) = cpu_to_be16(psta->dev_name_len); */
- put_unaligned_be16(psta->dev_name_len, pcur);
- pcur += 2;
-
- memcpy(pcur, psta->dev_name, psta->dev_name_len);
- pcur += psta->dev_name_len;
- }
-
- tmplen = (u8)(pcur-pstart);
-
- *pstart = (tmplen-1);
-
- attr_len += tmplen;
-
- /* pstart += tmplen; */
- pstart = pcur;
-
- }
-
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-
- if (attr_len>0)
- {
- len = rtw_set_p2p_attr_content23a(pbuf, P2P_ATTR_GROUP_INFO, attr_len, pdata_attr);
- }
-
- kfree(pdata_attr);
-
- return len;
-}
-
-static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- unsigned char category = WLAN_CATEGORY_VENDOR_SPECIFIC;/* P2P action frame */
- u32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_GO_DISC_REQUEST;
- u8 dialogToken = 0;
-
- DBG_8723A("[%s]\n", __func__);
-
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- {
- 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;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- fctrl = &pwlanhdr->frame_control;
- *fctrl = 0;
-
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN);
- memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- /* Build P2P action frame header */
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
-
- /* there is no IE in this P2P action frame */
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-}
-
-static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- unsigned char category = WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- u32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_DEVDISC_RESP;
- u8 p2pie[8] = { 0x00 };
- u32 p2pielen = 0;
-
- DBG_8723A("[%s]\n", __func__);
-
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- {
- 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;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- fctrl = &pwlanhdr->frame_control;
- *fctrl = 0;
-
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr2, pwdinfo->device_addr, ETH_ALEN);
- memcpy(pwlanhdr->addr3, pwdinfo->device_addr, ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- /* Build P2P public action frame header */
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *) &p2poui,
- &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
-
- /* Build P2P IE */
- /* P2P OUI */
- p2pielen = 0;
- p2pie[ p2pielen++ ] = 0x50;
- p2pie[ p2pielen++ ] = 0x6F;
- p2pie[ p2pielen++ ] = 0x9A;
- p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
-
- /* P2P_ATTR_STATUS */
- p2pielen += rtw_set_p2p_attr_content23a(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status);
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-}
-
-static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8* raddr, u8* frame_body, u16 config_method)
-{
- struct rtw_adapter *padapter = pwdinfo->padapter;
- unsigned char category = WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- u8 dialogToken = frame_body[7]; /* The Dialog Token of provisioning discovery request frame. */
- u32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_PROVISION_DISC_RESP;
- u8 wpsie[ 100 ] = { 0x00 };
- u8 wpsielen = 0;
-#ifdef CONFIG_8723AU_P2P
- u32 wfdielen = 0;
-#endif /* CONFIG_8723AU_P2P */
-
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- 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;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- fctrl = &pwlanhdr->frame_control;
- *fctrl = 0;
-
- memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
- memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *) &p2poui,
- &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
-
- wpsielen = 0;
- /* WPS OUI */
- /* u32*) (wpsie) = cpu_to_be32(WPSOUI); */
- put_unaligned_be32(WPSOUI, wpsie);
- wpsielen += 4;
-
- /* Config Method */
- /* Type: */
- /* u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD); */
- put_unaligned_be16(WPS_ATTR_CONF_METHOD, wpsie + wpsielen);
- wpsielen += 2;
-
- /* Length: */
- /* u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002); */
- put_unaligned_be16(0x0002, wpsie + wpsielen);
- wpsielen += 2;
-
- /* Value: */
- /* u16*) (wpsie + wpsielen) = cpu_to_be16(config_method); */
- put_unaligned_be16(config_method, wpsie + wpsielen);
- wpsielen += 2;
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
-
-#ifdef CONFIG_8723AU_P2P
- wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
-#endif /* CONFIG_8723AU_P2P */
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-
- return;
-}
-
-static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- unsigned char category = WLAN_CATEGORY_VENDOR_SPECIFIC;/* P2P action frame */
- u32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_PRESENCE_RESPONSE;
- u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
- u8 noa_attr_content[32] = { 0x00 };
- u32 p2pielen = 0;
-
- DBG_8723A("[%s]\n", __func__);
-
- if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
- {
- 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;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- fctrl = &pwlanhdr->frame_control;
- *fctrl = 0;
-
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN);
- memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- /* Build P2P action frame header */
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *) &p2poui,
- &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
-
- /* Add P2P IE header */
- /* P2P OUI */
- p2pielen = 0;
- p2pie[ p2pielen++ ] = 0x50;
- p2pie[ p2pielen++ ] = 0x6F;
- p2pie[ p2pielen++ ] = 0x9A;
- p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
-
- /* Add Status attribute in P2P IE */
- p2pielen += rtw_set_p2p_attr_content23a(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status);
-
- /* Add NoA attribute in P2P IE */
- noa_attr_content[0] = 0x1;/* index */
- noa_attr_content[1] = 0x0;/* CTWindow and OppPS Parameters */
-
- /* todo: Notice of Absence Descriptor(s) */
-
- p2pielen += rtw_set_p2p_attr_content23a(&p2pie[p2pielen], P2P_ATTR_NOA, 2, noa_attr_content);
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie,
- &pattrib->pktlen);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-}
-
-u32 build_beacon_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
- u16 capability = 0;
- u32 len = 0, p2pielen = 0;
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[ p2pielen++ ] = 0x50;
- p2pie[ p2pielen++ ] = 0x6F;
- p2pie[ p2pielen++ ] = 0x9A;
- p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
-
- /* According to the P2P Specification, the beacon frame should contain 3 P2P attributes */
- /* 1. P2P Capability */
- /* 2. P2P Device ID */
- /* 3. Notice of Absence (NOA) */
-
- /* P2P Capability ATTR */
- /* Type: */
- /* Length: */
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- /* Be able to participate in additional P2P Groups and */
- /* support the P2P Invitation Procedure */
- /* Group Capability Bitmap, 1 byte */
- capability = P2P_DEVCAP_INVITATION_PROC|P2P_DEVCAP_CLIENT_DISCOVERABILITY;
- capability |= ((P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS) << 8);
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
- capability |= (P2P_GRPCAP_GROUP_FORMATION<<8);
-
- capability = cpu_to_le16(capability);
-
- p2pielen += rtw_set_p2p_attr_content23a(&p2pie[p2pielen], P2P_ATTR_CAPABILITY, 2, (u8*)&capability);
-
- /* P2P Device ID ATTR */
- p2pielen += rtw_set_p2p_attr_content23a(&p2pie[p2pielen], P2P_ATTR_DEVICE_ID, ETH_ALEN, pwdinfo->device_addr);
-
- /* Notice of Absence ATTR */
- /* Type: */
- /* Length: */
- /* Value: */
-
- /* go_add_noa_attr(pwdinfo); */
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len);
-
- return len;
-}
-
-#ifdef CONFIG_8723AU_P2P
-u32 build_beacon_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 len = 0, wfdielen = 0;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
-
- /* WFD OUI */
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
-
- /* Commented by Albert 20110812 */
- /* According to the WFD Specification, the beacon frame should contain 4 WFD attributes */
- /* 1. WFD Device Information */
- /* 2. Associated BSSID */
- /* 3. Coupled Sink Information */
-
- /* WFD Device Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value1: */
- /* WFD device information */
-
- if (P2P_ROLE_GO == pwdinfo->role)
- {
- if (is_any_client_associated(pwdinfo->padapter))
- {
- /* WFD primary sink + WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_WSD, wfdie + wfdielen);
- }
- else
- {
- /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_SESSION_AVAIL |
- WFD_DEVINFO_WSD, wfdie + wfdielen);
- }
-
- }
- else
- {
- /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_SESSION_AVAIL |
- WFD_DEVINFO_WSD, wfdie + wfdielen);
- }
-
- wfdielen += 2;
-
- /* Value2: */
- /* Session Management Control Port */
- /* Default TCP port for RTSP messages is 554 */
- put_unaligned_be16(pwfd_info->rtsp_ctrlport, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value3: */
- /* WFD Device Maximum Throughput */
- /* 300Mbps is the maximum throughput */
- put_unaligned_be16(300, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Associated BSSID ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Associated BSSID */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
- }
- else
- {
- memset(wfdie + wfdielen, 0x00, ETH_ALEN);
- }
-
- wfdielen += ETH_ALEN;
-
- /* Coupled Sink Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0007, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Coupled Sink Status bitmap */
- /* Not coupled/available for Coupling */
- wfdie[ wfdielen++ ] = 0;
- /* MAC Addr. */
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
-
- return len;
-}
-
-u32 build_probe_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 len = 0, wfdielen = 0;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
-
- /* WFD OUI */
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
-
- /* Commented by Albert 20110812 */
- /* According to the WFD Specification, the probe request frame should contain 4 WFD attributes */
- /* 1. WFD Device Information */
- /* 2. Associated BSSID */
- /* 3. Coupled Sink Information */
-
- /* WFD Device Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value1: */
- /* WFD device information */
-
- if (1 == pwdinfo->wfd_tdls_enable)
- {
- /* WFD primary sink + available for WFD session + WiFi TDLS mode + WSC (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_SESSION_AVAIL |
- WFD_DEVINFO_WSD |
- WFD_DEVINFO_PC_TDLS, wfdie + wfdielen);
- }
- else
- {
- /* WFD primary sink + available for WFD session + WiFi Direct mode + WSC (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_SESSION_AVAIL |
- WFD_DEVINFO_WSD, wfdie + wfdielen);
- }
-
- wfdielen += 2;
-
- /* Value2: */
- /* Session Management Control Port */
- /* Default TCP port for RTSP messages is 554 */
- put_unaligned_be16(pwfd_info->rtsp_ctrlport, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value3: */
- /* WFD Device Maximum Throughput */
- /* 300Mbps is the maximum throughput */
- put_unaligned_be16(300, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Associated BSSID ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Associated BSSID */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
- }
- else
- {
- memset(wfdie + wfdielen, 0x00, ETH_ALEN);
- }
-
- wfdielen += ETH_ALEN;
-
- /* Coupled Sink Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0007, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Coupled Sink Status bitmap */
- /* Not coupled/available for Coupling */
- wfdie[ wfdielen++ ] = 0;
- /* MAC Addr. */
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
-
- return len;
-}
-
-u32 build_probe_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 tunneled)
-{
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 len = 0, wfdielen = 0;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
-
- /* WFD OUI */
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
-
- /* Commented by Albert 20110812 */
- /* According to the WFD Specification, the probe response frame should contain 4 WFD attributes */
- /* 1. WFD Device Information */
- /* 2. Associated BSSID */
- /* 3. Coupled Sink Information */
- /* 4. WFD Session Information */
-
- /* WFD Device Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value1: */
- /* WFD device information */
- /* WFD primary sink + available for WFD session + WiFi Direct mode */
-
- if (true == pwdinfo->session_available)
- {
- if (P2P_ROLE_GO == pwdinfo->role)
- {
- if (is_any_client_associated(pwdinfo->padapter))
- {
- if (pwdinfo->wfd_tdls_enable)
- {
- /* TDLS mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT, wfdie + wfdielen);
- }
- else
- {
- /* WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT, wfdie + wfdielen);
- }
- }
- else
- {
- if (pwdinfo->wfd_tdls_enable)
- {
- /* available for WFD session + TDLS mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT, wfdie + wfdielen);
- }
- else
- {
- /* available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT, wfdie + wfdielen);
- }
- }
- }
- else
- {
- if (pwdinfo->wfd_tdls_enable)
- {
- /* available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_SESSION_AVAIL |
- WFD_DEVINFO_WSD |
- WFD_DEVINFO_PC_TDLS |
- WFD_DEVINFO_HDCP_SUPPORT,
- wfdie + wfdielen);
- }
- else
- {
-
- /* available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_SESSION_AVAIL |
- WFD_DEVINFO_WSD |
- WFD_DEVINFO_HDCP_SUPPORT,
- wfdie + wfdielen);
- }
- }
- }
- else
- {
- if (pwdinfo->wfd_tdls_enable)
- {
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_WSD |
- WFD_DEVINFO_PC_TDLS |
- WFD_DEVINFO_HDCP_SUPPORT,
- wfdie + wfdielen);
- }
- else
- {
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_WSD |
- WFD_DEVINFO_HDCP_SUPPORT,
- wfdie + wfdielen);
- }
-
- }
-
- wfdielen += 2;
-
- /* Value2: */
- /* Session Management Control Port */
- /* Default TCP port for RTSP messages is 554 */
- put_unaligned_be16(pwfd_info->rtsp_ctrlport, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value3: */
- /* WFD Device Maximum Throughput */
- /* 300Mbps is the maximum throughput */
- put_unaligned_be16(300, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Associated BSSID ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Associated BSSID */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
- }
- else
- {
- memset(wfdie + wfdielen, 0x00, ETH_ALEN);
- }
-
- wfdielen += ETH_ALEN;
-
- /* Coupled Sink Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0007, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Coupled Sink Status bitmap */
- /* Not coupled/available for Coupling */
- wfdie[ wfdielen++ ] = 0;
- /* MAC Addr. */
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- {
- /* WFD Session Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0000, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Todo: to add the list of WFD device info descriptor in WFD group. */
-
- }
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
-
- return len;
-}
-
-u32 build_assoc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 len = 0, wfdielen = 0;
- struct rtw_adapter *padapter = NULL;
- struct mlme_priv *pmlmepriv = NULL;
- struct wifi_display_info *pwfd_info = NULL;
-
- /* WFD OUI */
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
- {
- return 0;
- }
-
- padapter = pwdinfo->padapter;
- pmlmepriv = &padapter->mlmepriv;
- pwfd_info = padapter->wdinfo.wfd_info;
-
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
-
- /* Commented by Albert 20110812 */
- /* According to the WFD Specification, the probe request frame should contain 4 WFD attributes */
- /* 1. WFD Device Information */
- /* 2. Associated BSSID */
- /* 3. Coupled Sink Information */
-
- /* WFD Device Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value1: */
- /* WFD device information */
- /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_SESSION_AVAIL |
- WFD_DEVINFO_WSD, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value2: */
- /* Session Management Control Port */
- /* Default TCP port for RTSP messages is 554 */
- put_unaligned_be16(pwfd_info->rtsp_ctrlport, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value3: */
- /* WFD Device Maximum Throughput */
- /* 300Mbps is the maximum throughput */
- put_unaligned_be16(300, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Associated BSSID ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Associated BSSID */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
- }
- else
- {
- memset(wfdie + wfdielen, 0x00, ETH_ALEN);
- }
-
- wfdielen += ETH_ALEN;
-
- /* Coupled Sink Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0007, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Coupled Sink Status bitmap */
- /* Not coupled/available for Coupling */
- wfdie[ wfdielen++ ] = 0;
- /* MAC Addr. */
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
-
- return len;
-}
-
-u32 build_assoc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 len = 0, wfdielen = 0;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
-
- /* WFD OUI */
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
-
- /* Commented by Albert 20110812 */
- /* According to the WFD Specification, the probe request frame should contain 4 WFD attributes */
- /* 1. WFD Device Information */
- /* 2. Associated BSSID */
- /* 3. Coupled Sink Information */
-
- /* WFD Device Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value1: */
- /* WFD device information */
- /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_SESSION_AVAIL |
- WFD_DEVINFO_WSD, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value2: */
- /* Session Management Control Port */
- /* Default TCP port for RTSP messages is 554 */
- put_unaligned_be16(pwfd_info->rtsp_ctrlport, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value3: */
- /* WFD Device Maximum Throughput */
- /* 300Mbps is the maximum throughput */
- put_unaligned_be16(300, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Associated BSSID ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Associated BSSID */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
- }
- else
- {
- memset(wfdie + wfdielen, 0x00, ETH_ALEN);
- }
-
- wfdielen += ETH_ALEN;
-
- /* Coupled Sink Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0007, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Coupled Sink Status bitmap */
- /* Not coupled/available for Coupling */
- wfdie[ wfdielen++ ] = 0;
- /* MAC Addr. */
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
-
- return len;
-}
-
-u32 build_nego_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 len = 0, wfdielen = 0;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
-
- /* WFD OUI */
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
-
- /* Commented by Albert 20110825 */
- /* According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes */
- /* 1. WFD Device Information */
- /* 2. Associated BSSID (Optional) */
- /* 3. Local IP Adress (Optional) */
-
- /* WFD Device Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value1: */
- /* WFD device information */
- /* WFD primary sink + WiFi Direct mode + WSD (WFD Service Discovery) + WFD Session Available */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL,
- wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value2: */
- /* Session Management Control Port */
- /* Default TCP port for RTSP messages is 554 */
- put_unaligned_be16(pwfd_info->rtsp_ctrlport, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value3: */
- /* WFD Device Maximum Throughput */
- /* 300Mbps is the maximum throughput */
- put_unaligned_be16(300, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Associated BSSID ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Associated BSSID */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
- }
- else
- {
- memset(wfdie + wfdielen, 0x00, ETH_ALEN);
- }
-
- wfdielen += ETH_ALEN;
-
- /* Coupled Sink Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0007, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Coupled Sink Status bitmap */
- /* Not coupled/available for Coupling */
- wfdie[ wfdielen++ ] = 0;
- /* MAC Addr. */
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
-
- return len;
-}
-
-u32 build_nego_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 len = 0, wfdielen = 0;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
-
- /* WFD OUI */
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
-
- /* Commented by Albert 20110825 */
- /* According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes */
- /* 1. WFD Device Information */
- /* 2. Associated BSSID (Optional) */
- /* 3. Local IP Adress (Optional) */
-
- /* WFD Device Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value1: */
- /* WFD device information */
- /* WFD primary sink + WiFi Direct mode + WSD (WFD Service Discovery) + WFD Session Available */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL,
- wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value2: */
- /* Session Management Control Port */
- /* Default TCP port for RTSP messages is 554 */
- put_unaligned_be16(pwfd_info->rtsp_ctrlport, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value3: */
- /* WFD Device Maximum Throughput */
- /* 300Mbps is the maximum throughput */
- put_unaligned_be16(300, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Associated BSSID ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Associated BSSID */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
- }
- else
- {
- memset(wfdie + wfdielen, 0x00, ETH_ALEN);
- }
-
- wfdielen += ETH_ALEN;
-
- /* Coupled Sink Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0007, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Coupled Sink Status bitmap */
- /* Not coupled/available for Coupling */
- wfdie[ wfdielen++ ] = 0;
- /* MAC Addr. */
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
-
- return len;
-}
-
-u32 build_nego_confirm_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 len = 0, wfdielen = 0;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
-
- /* WFD OUI */
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
-
- /* Commented by Albert 20110825 */
- /* According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes */
- /* 1. WFD Device Information */
- /* 2. Associated BSSID (Optional) */
- /* 3. Local IP Adress (Optional) */
-
- /* WFD Device Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value1: */
- /* WFD device information */
- /* WFD primary sink + WiFi Direct mode + WSD (WFD Service Discovery) + WFD Session Available */
- put_unaligned_be16(pwfd_info->wfd_device_type | WFD_DEVINFO_WSD |
- WFD_DEVINFO_SESSION_AVAIL, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value2: */
- /* Session Management Control Port */
- /* Default TCP port for RTSP messages is 554 */
- put_unaligned_be16(pwfd_info->rtsp_ctrlport, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value3: */
- /* WFD Device Maximum Throughput */
- /* 300Mbps is the maximum throughput */
- put_unaligned_be16(300, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Associated BSSID ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Associated BSSID */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
- }
- else
- {
- memset(wfdie + wfdielen, 0x00, ETH_ALEN);
- }
-
- wfdielen += ETH_ALEN;
-
- /* Coupled Sink Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0007, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Coupled Sink Status bitmap */
- /* Not coupled/available for Coupling */
- wfdie[ wfdielen++ ] = 0;
- /* MAC Addr. */
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
-
- return len;
-}
-
-u32 build_invitation_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 len = 0, wfdielen = 0;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
-
- /* WFD OUI */
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
-
- /* Commented by Albert 20110825 */
- /* According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes */
- /* 1. WFD Device Information */
- /* 2. Associated BSSID (Optional) */
- /* 3. Local IP Adress (Optional) */
-
- /* WFD Device Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value1: */
- /* WFD device information */
- /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD,
- wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value2: */
- /* Session Management Control Port */
- /* Default TCP port for RTSP messages is 554 */
- put_unaligned_be16(pwfd_info->rtsp_ctrlport, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value3: */
- /* WFD Device Maximum Throughput */
- /* 300Mbps is the maximum throughput */
- put_unaligned_be16(300, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Associated BSSID ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Associated BSSID */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
- }
- else
- {
- memset(wfdie + wfdielen, 0x00, ETH_ALEN);
- }
-
- wfdielen += ETH_ALEN;
-
- /* Coupled Sink Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0007, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Coupled Sink Status bitmap */
- /* Not coupled/available for Coupling */
- wfdie[ wfdielen++ ] = 0;
- /* MAC Addr. */
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
-
- if (P2P_ROLE_GO == pwdinfo->role)
- {
- /* WFD Session Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0000, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Todo: to add the list of WFD device info descriptor in WFD group. */
-
- }
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
-
- return len;
-}
-
-u32 build_invitation_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 len = 0, wfdielen = 0;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
-
- /* WFD OUI */
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
-
- /* Commented by Albert 20110825 */
- /* According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes */
- /* 1. WFD Device Information */
- /* 2. Associated BSSID (Optional) */
- /* 3. Local IP Adress (Optional) */
-
- /* WFD Device Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value1: */
- /* WFD device information */
- /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD,
- wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value2: */
- /* Session Management Control Port */
- /* Default TCP port for RTSP messages is 554 */
- put_unaligned_be16(pwfd_info->rtsp_ctrlport, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value3: */
- /* WFD Device Maximum Throughput */
- /* 300Mbps is the maximum throughput */
- put_unaligned_be16(300, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Associated BSSID ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Associated BSSID */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
- }
- else
- {
- memset(wfdie + wfdielen, 0x00, ETH_ALEN);
- }
-
- wfdielen += ETH_ALEN;
-
- /* Coupled Sink Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0007, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Coupled Sink Status bitmap */
- /* Not coupled/available for Coupling */
- wfdie[ wfdielen++ ] = 0;
- /* MAC Addr. */
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
-
- if (P2P_ROLE_GO == pwdinfo->role)
- {
- /* WFD Session Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0000, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Todo: to add the list of WFD device info descriptor in WFD group. */
-
- }
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
-
- return len;
-}
-
-u32 build_provdisc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 len = 0, wfdielen = 0;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
-
- /* WFD OUI */
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
-
- /* Commented by Albert 20110825 */
- /* According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes */
- /* 1. WFD Device Information */
- /* 2. Associated BSSID (Optional) */
- /* 3. Local IP Adress (Optional) */
-
- /* WFD Device Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value1: */
- /* WFD device information */
- /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD,
- wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value2: */
- /* Session Management Control Port */
- /* Default TCP port for RTSP messages is 554 */
- put_unaligned_be16(pwfd_info->rtsp_ctrlport, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value3: */
- /* WFD Device Maximum Throughput */
- /* 300Mbps is the maximum throughput */
- put_unaligned_be16(300, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Associated BSSID ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Associated BSSID */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
- }
- else
- {
- memset(wfdie + wfdielen, 0x00, ETH_ALEN);
- }
-
- wfdielen += ETH_ALEN;
-
- /* Coupled Sink Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0007, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Coupled Sink Status bitmap */
- /* Not coupled/available for Coupling */
- wfdie[ wfdielen++ ] = 0;
- /* MAC Addr. */
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
-
- return len;
-}
-
-u32 build_provdisc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 len = 0, wfdielen = 0;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
-
- /* WFD OUI */
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
-
- /* Commented by Albert 20110825 */
- /* According to the WFD Specification, the provision discovery response frame should contain 3 WFD attributes */
- /* 1. WFD Device Information */
- /* 2. Associated BSSID (Optional) */
- /* 3. Local IP Adress (Optional) */
-
- /* WFD Device Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value1: */
- /* WFD device information */
- /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
- put_unaligned_be16(pwfd_info->wfd_device_type |
- WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD,
- wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value2: */
- /* Session Management Control Port */
- /* Default TCP port for RTSP messages is 554 */
- put_unaligned_be16(pwfd_info->rtsp_ctrlport, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value3: */
- /* WFD Device Maximum Throughput */
- /* 300Mbps is the maximum throughput */
- put_unaligned_be16(300, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Associated BSSID ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0006, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Associated BSSID */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- {
- memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
- }
- else
- {
- memset(wfdie + wfdielen, 0x00, ETH_ALEN);
- }
-
- wfdielen += ETH_ALEN;
-
- /* Coupled Sink Information ATTR */
- /* Type: */
- wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
-
- /* Length: */
- /* Note: In the WFD specification, the size of length field is 2. */
- put_unaligned_be16(0x0007, wfdie + wfdielen);
- wfdielen += 2;
-
- /* Value: */
- /* Coupled Sink Status bitmap */
- /* Not coupled/available for Coupling */
- wfdie[ wfdielen++ ] = 0;
- /* MAC Addr. */
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
- wfdie[ wfdielen++ ] = 0;
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
-
- return len;
-}
-
-#endif /* CONFIG_8723AU_P2P */
-
-u32 build_probe_resp_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
- u32 len = 0, p2pielen = 0;
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[ p2pielen++ ] = 0x50;
- p2pie[ p2pielen++ ] = 0x6F;
- p2pie[ p2pielen++ ] = 0x9A;
- p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20100907 */
- /* According to the P2P Specification, the probe response frame should contain 5 P2P attributes */
- /* 1. P2P Capability */
- /* 2. Extended Listen Timing */
- /* 3. Notice of Absence (NOA) (Only GO needs this) */
- /* 4. Device Info */
- /* 5. Group Info (Only GO need this) */
-
- /* P2P Capability ATTR */
- /* Type: */
- p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002); */
- put_unaligned_le16(0x0002, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
-
- /* Group Capability Bitmap, 1 byte */
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- {
- p2pie[ p2pielen ] = (P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS);
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
- p2pie[ p2pielen ] |= P2P_GRPCAP_GROUP_FORMATION;
-
- p2pielen++;
- }
- else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
- {
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported)
- p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
- else
- p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
- }
-
- /* Extended Listen Timing ATTR */
- /* Type: */
- p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
-
- /* Length: */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0004); */
- put_unaligned_le16(0x0004, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Value: */
- /* Availability Period */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF); */
- put_unaligned_le16(0xFFFF, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Availability Interval */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF); */
- put_unaligned_le16(0xFFFF, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Notice of Absence ATTR */
- /* Type: */
- /* Length: */
- /* Value: */
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- {
- /* go_add_noa_attr(pwdinfo); */
- }
-
- /* Device Info ATTR */
- /* Type: */
- p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
- /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); */
- put_unaligned_le16(21 + pwdinfo->device_name_len, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address */
- memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Config Method */
- /* This field should be big endian. Noted by P2P specification. */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm); */
- put_unaligned_be16(pwdinfo->supported_wps_cm, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Primary Device Type */
- /* Category ID */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); */
- put_unaligned_be16(WPS_PDT_CID_MULIT_MEDIA, p2pie + p2pielen);
- p2pielen += 2;
-
- /* OUI */
- /* u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI); */
- put_unaligned_be32(WPSOUI, p2pie + p2pielen);
- p2pielen += 4;
-
- /* Sub Category ID */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); */
- put_unaligned_be16(WPS_PDT_SCID_MEDIA_SERVER, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Number of Secondary Device Types */
- p2pie[ p2pielen++ ] = 0x00; /* No Secondary Device Type List */
-
- /* Device Name */
- /* Type: */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
- put_unaligned_be16(WPS_ATTR_DEVICE_NAME, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Length: */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); */
- put_unaligned_be16(pwdinfo->device_name_len, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
- p2pielen += pwdinfo->device_name_len;
-
- /* Group Info ATTR */
- /* Type: */
- /* Length: */
- /* Value: */
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- {
- p2pielen += go_add_group_info_attr(pwdinfo, p2pie + p2pielen);
- }
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len);
-
- return len;
-}
-
-u32 build_prov_disc_request_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pbuf, u8* pssid, u8 ussidlen, u8* pdev_raddr)
-{
- u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
- u32 len = 0, p2pielen = 0;
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[ p2pielen++ ] = 0x50;
- p2pie[ p2pielen++ ] = 0x6F;
- p2pie[ p2pielen++ ] = 0x9A;
- p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20110301 */
- /* According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes */
- /* 1. P2P Capability */
- /* 2. Device Info */
- /* 3. Group ID (When joining an operating P2P Group) */
-
- /* P2P Capability ATTR */
- /* Type: */
- p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002); */
- put_unaligned_le16(0x0002, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
-
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported)
- p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
- else
- p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
-
- /* Device Info ATTR */
- /* Type: */
- p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
- /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); */
- put_unaligned_le16(21 + pwdinfo->device_name_len, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address */
- memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Config Method */
- /* This field should be big endian. Noted by P2P specification. */
- if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC)
- {
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC); */
- put_unaligned_be16(WPS_CONFIG_METHOD_PBC, p2pie + p2pielen);
- }
- else
- {
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY); */
- put_unaligned_be16(WPS_CONFIG_METHOD_DISPLAY, p2pie + p2pielen);
- }
-
- p2pielen += 2;
-
- /* Primary Device Type */
- /* Category ID */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); */
- put_unaligned_be16(WPS_PDT_CID_MULIT_MEDIA, p2pie + p2pielen);
- p2pielen += 2;
-
- /* OUI */
- /* u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI); */
- put_unaligned_be32(WPSOUI, p2pie + p2pielen);
- p2pielen += 4;
-
- /* Sub Category ID */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); */
- put_unaligned_be16(WPS_PDT_SCID_MEDIA_SERVER, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Number of Secondary Device Types */
- p2pie[ p2pielen++ ] = 0x00; /* No Secondary Device Type List */
-
- /* Device Name */
- /* Type: */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
- put_unaligned_be16(WPS_ATTR_DEVICE_NAME, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Length: */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); */
- put_unaligned_be16(pwdinfo->device_name_len, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
- p2pielen += pwdinfo->device_name_len;
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
- {
- /* Added by Albert 2011/05/19 */
- /* In this case, the pdev_raddr is the device address of the group owner. */
-
- /* P2P Group ID ATTR */
- /* Type: */
- p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
-
- /* Length: */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + ussidlen); */
- put_unaligned_le16(ETH_ALEN + ussidlen, p2pie + p2pielen);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pdev_raddr, ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- memcpy(p2pie + p2pielen, pssid, ussidlen);
- p2pielen += ussidlen;
-
- }
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len);
-
- return len;
-}
-
-u32 build_assoc_resp_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status_code)
-{
- u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
- u32 len = 0, p2pielen = 0;
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[ p2pielen++ ] = 0x50;
- p2pie[ p2pielen++ ] = 0x6F;
- p2pie[ p2pielen++ ] = 0x9A;
- p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
-
- /* According to the P2P Specification, the Association response frame should contain 2 P2P attributes */
- /* 1. Status */
- /* 2. Extended Listen Timing (optional) */
-
- /* Status ATTR */
- p2pielen += rtw_set_p2p_attr_content23a(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status_code);
-
- /* Extended Listen Timing ATTR */
- /* Type: */
- /* Length: */
- /* Value: */
-
- pbuf = rtw_set_ie23a(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len);
-
- return len;
-}
-
-u32 build_deauth_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u32 len = 0;
-
- return len;
-}
-
-u32 process_probe_req_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- u8 *p;
- u32 ret = false;
- u8 *p2pie;
- u32 p2pielen = 0;
- int ssid_len = 0, rate_cnt = 0;
-
- p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + _PROBEREQ_IE_OFFSET_, _SUPPORTEDRATES_IE_, (int *)&rate_cnt,
- len - sizeof(struct ieee80211_hdr_3addr) - _PROBEREQ_IE_OFFSET_);
-
- if (rate_cnt <= 4)
- {
- int i, g_rate = 0;
-
- for (i = 0; i < rate_cnt; i++)
- {
- if (((*(p + 2 + i) & 0xff) != 0x02) &&
- ((*(p + 2 + i) & 0xff) != 0x04) &&
- ((*(p + 2 + i) & 0xff) != 0x0B) &&
- ((*(p + 2 + i) & 0xff) != 0x16))
- {
- g_rate = 1;
- }
- }
-
- if (g_rate == 0)
- {
- /* There is no OFDM rate included in SupportedRates IE of this probe request frame */
- /* The driver should response this probe request. */
- return ret;
- }
- }
- else
- {
- /* rate_cnt > 4 means the SupportRates IE contains the OFDM rate because the count of CCK rates are 4. */
- /* We should proceed the following check for this probe request. */
- }
-
- /* Added comments by Albert 20100906 */
- /* There are several items we should check here. */
- /* 1. This probe request frame must contain the P2P IE. (Done) */
- /* 2. This probe request frame must contain the wildcard SSID. (Done) */
- /* 3. Wildcard BSSID. (Todo) */
- /* 4. Destination Address. (Done in mgt_dispatcher23a function) */
- /* 5. Requested Device Type in WSC IE. (Todo) */
- /* 6. Device ID attribute in P2P IE. (Todo) */
-
- p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ssid_len,
- len - sizeof(struct ieee80211_hdr_3addr) - _PROBEREQ_IE_OFFSET_);
-
- ssid_len &= 0xff; /* Just last 1 byte is valid for ssid len of the probe request */
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- {
- if ((p2pie = rtw_get_p2p_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + _PROBEREQ_IE_OFFSET_, len - sizeof(struct ieee80211_hdr_3addr) - _PROBEREQ_IE_OFFSET_, NULL, &p2pielen)))
- {
- if ((p) && !memcmp((void *)(p+2), (void *)pwdinfo->p2p_wildcard_ssid, 7))
- {
- /* todo: */
- /* Check Requested Device Type attributes in WSC IE. */
- /* Check Device ID attribute in P2P IE */
-
- ret = true;
- }
- else if ((p != NULL) && (ssid_len == 0))
- {
- ret = true;
- }
- }
- else
- {
- /* non -p2p device */
- }
-
- }
-
- return ret;
-}
-
-u32 process_assoc_req_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pframe, uint len, struct sta_info *psta)
-{
- u8 status_code = P2P_STATUS_SUCCESS;
- u8 *pbuf, *pattr_content = NULL;
- u32 attr_contentlen = 0;
- u16 cap_attr = 0;
- unsigned short ie_offset;
- u8 * ies;
- u32 ies_len;
- u8 * p2p_ie;
- u32 p2p_ielen = 0;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)pframe;
-
- if (!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- return P2P_STATUS_FAIL_REQUEST_UNABLE;
-
- if (ieee80211_is_assoc_req(hdr->frame_control))
- ie_offset = _ASOCREQ_IE_OFFSET_;
- else /* WIFI_REASSOCREQ */
- ie_offset = _REASOCREQ_IE_OFFSET_;
-
- ies = pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset;
- ies_len = len - sizeof(struct ieee80211_hdr_3addr) - ie_offset;
-
- p2p_ie = rtw_get_p2p_ie23a(ies, ies_len, NULL, &p2p_ielen);
-
- if (!p2p_ie)
- {
- DBG_8723A("[%s] P2P IE not Found!!\n", __func__);
- status_code = P2P_STATUS_FAIL_INVALID_PARAM;
- }
- else
- {
- DBG_8723A("[%s] P2P IE Found!!\n", __func__);
- }
-
- while (p2p_ie)
- {
- /* Check P2P Capability ATTR */
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen))
- {
- DBG_8723A("[%s] Got P2P Capability Attr!!\n", __func__);
- cap_attr = le16_to_cpu(cap_attr);
- psta->dev_cap = cap_attr&0xff;
- }
-
- /* Check Extended Listen Timing ATTR */
-
- /* Check P2P Device Info ATTR */
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, NULL, (uint*)&attr_contentlen))
- {
- DBG_8723A("[%s] Got P2P DEVICE INFO Attr!!\n", __func__);
- pattr_content = pbuf = kzalloc(attr_contentlen,
- GFP_ATOMIC);
- if (pattr_content) {
- u8 num_of_secdev_type;
- u16 dev_name_len;
-
- rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, pattr_content, (uint*)&attr_contentlen);
-
- memcpy(psta->dev_addr, pattr_content, ETH_ALEN);/* P2P Device Address */
-
- pattr_content += ETH_ALEN;
-
- memcpy(&psta->config_methods, pattr_content, 2);/* Config Methods */
- psta->config_methods = be16_to_cpu(psta->config_methods);
-
- pattr_content += 2;
-
- memcpy(psta->primary_dev_type, pattr_content, 8);
-
- pattr_content += 8;
-
- num_of_secdev_type = *pattr_content;
- pattr_content += 1;
-
- if (num_of_secdev_type == 0)
- {
- psta->num_of_secdev_type = 0;
- }
- else
- {
- u32 len;
-
- psta->num_of_secdev_type = num_of_secdev_type;
-
- len = (sizeof(psta->secdev_types_list)<(num_of_secdev_type*8)) ? (sizeof(psta->secdev_types_list)) : (num_of_secdev_type*8);
-
- memcpy(psta->secdev_types_list, pattr_content, len);
-
- pattr_content += (num_of_secdev_type*8);
- }
-
- /* dev_name_len = attr_contentlen - ETH_ALEN - 2 - 8 - 1 - (num_of_secdev_type*8); */
- psta->dev_name_len = 0;
- if (WPS_ATTR_DEVICE_NAME == be16_to_cpu(*(u16*)pattr_content))
- {
- dev_name_len = be16_to_cpu(*(u16*)(pattr_content+2));
-
- psta->dev_name_len = (sizeof(psta->dev_name)<dev_name_len) ? sizeof(psta->dev_name):dev_name_len;
-
- memcpy(psta->dev_name, pattr_content+4, psta->dev_name_len);
- }
-
- kfree(pbuf);
-
- }
-
- }
-
- /* Get the next P2P IE */
- p2p_ie = rtw_get_p2p_ie23a(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
-
- }
-
- return status_code;
-}
-
-u32 process_p2p_devdisc_req23a(struct wifidirect_info *pwdinfo, u8 *pframe,
- uint len)
-{
- u8 *frame_body;
- u8 status, dialogToken;
- struct sta_info *psta = NULL;
- struct rtw_adapter *padapter = pwdinfo->padapter;
- struct sta_priv *pstapriv = &padapter->stapriv;
- u8 *p2p_ie;
- u32 p2p_ielen = 0;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) pframe;
-
- frame_body = (unsigned char *)
- (pframe + sizeof(struct ieee80211_hdr_3addr));
-
- dialogToken = frame_body[7];
- status = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
-
- if ((p2p_ie = rtw_get_p2p_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_,
- len - _PUBLIC_ACTION_IE_OFFSET_, NULL,
- &p2p_ielen))) {
- u8 groupid[38] = { 0x00 };
- u8 dev_addr[ETH_ALEN] = { 0x00 };
- u32 attr_contentlen = 0;
-
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen,
- P2P_ATTR_GROUP_ID, groupid,
- &attr_contentlen)) {
- if (!memcmp(pwdinfo->device_addr, groupid, ETH_ALEN) &&
- !memcmp(pwdinfo->p2p_group_ssid, groupid + ETH_ALEN,
- pwdinfo->p2p_group_ssid_len)) {
- attr_contentlen = 0;
-
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen,
- P2P_ATTR_DEVICE_ID,
- dev_addr,
- &attr_contentlen)) {
- struct list_head *phead, *plist, *ptmp;
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- phead = &pstapriv->asoc_list;
-
- list_for_each_safe(plist, ptmp, phead) {
- psta = container_of(plist, struct sta_info, asoc_list);
-
- if (psta->is_p2p_device && (psta->dev_cap&P2P_DEVCAP_CLIENT_DISCOVERABILITY) &&
- !memcmp(psta->dev_addr, dev_addr, ETH_ALEN))
- {
- /* spin_unlock_bh(&pstapriv->asoc_list_lock); */
- /* issue GO Discoverability Request */
- issue_group_disc_req(pwdinfo, psta->hwaddr);
- /* spin_lock_bh(&pstapriv->asoc_list_lock); */
- status = P2P_STATUS_SUCCESS;
- break;
- } else {
- status = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- }
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
- } else {
- status = P2P_STATUS_FAIL_INVALID_PARAM;
- }
- } else {
- status = P2P_STATUS_FAIL_INVALID_PARAM;
- }
- }
- }
-
- /* issue Device Discoverability Response */
- issue_p2p_devdisc_resp(pwdinfo, hdr->addr2, status, dialogToken);
-
- return (status == P2P_STATUS_SUCCESS) ? true:false;
-}
-
-u32 process_p2p_devdisc_resp23a(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- return true;
-}
-
-u8 process_p2p_provdisc_req23a(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len)
-{
- u8 *frame_body;
- u8 *wpsie;
- u8 *ptr = NULL;
- uint wps_ielen = 0, attr_contentlen = 0;
- u16 uconfig_method = 0;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)pframe;
-
- frame_body = (pframe + sizeof(struct ieee80211_hdr_3addr));
-
- wpsie = rtw_get_wps_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_,
- len - _PUBLIC_ACTION_IE_OFFSET_, NULL,
- &wps_ielen);
- if (!wpsie)
- goto out;
-
- if (!rtw_get_wps_attr_content23a(wpsie, wps_ielen, WPS_ATTR_CONF_METHOD,
- (u8 *)&uconfig_method, &attr_contentlen))
- goto out;
-
- uconfig_method = be16_to_cpu(uconfig_method);
- ptr = pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req;
-
- switch (uconfig_method)
- {
- case WPS_CM_DISPLYA:
- memcpy(ptr, "dis", 3);
- break;
-
- case WPS_CM_LABEL:
- memcpy(ptr, "lab", 3);
- break;
-
- case WPS_CM_PUSH_BUTTON:
- memcpy(ptr, "pbc", 3);
- break;
-
- case WPS_CM_KEYPAD:
- memcpy(ptr, "pad", 3);
- break;
- }
- issue_p2p_provision_resp(pwdinfo, hdr->addr2, frame_body,
- uconfig_method);
-
-out:
- DBG_8723A("[%s] config method = %s\n", __func__, ptr);
-
- return true;
-}
-
-u8 process_p2p_provdisc_resp23a(struct wifidirect_info *pwdinfo, u8 *pframe)
-{
-
- return true;
-}
-
-static u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 ch_cnt, u8 *peer_ch_list)
-{
- u8 i = 0, j = 0;
- u8 temp = 0;
- u8 ch_no = 0;
- ch_content += 3;
- ch_cnt -= 3;
-
- while(ch_cnt > 0)
- {
- ch_content += 1;
- ch_cnt -= 1;
- temp = *ch_content;
- for (i = 0 ; i < temp ; i++, j++)
- {
- peer_ch_list[j] = *(ch_content + 1 + i);
- }
- ch_content += (temp + 1);
- ch_cnt -= (temp + 1);
- ch_no += temp ;
- }
-
- return ch_no;
-}
-
-static u8 rtw_p2p_ch_inclusion(struct mlme_ext_priv *pmlmeext, u8 *peer_ch_list, u8 peer_ch_num, u8 *ch_list_inclusioned)
-{
- int i = 0, j = 0, temp = 0;
- u8 ch_no = 0;
-
- for (i = 0; i < peer_ch_num; i++)
- {
- for (j = temp; j < pmlmeext->max_chan_nums; j++)
- {
- if (*(peer_ch_list + i) == pmlmeext->channel_set[ j ].ChannelNum)
- {
- ch_list_inclusioned[ ch_no++ ] = *(peer_ch_list + i);
- temp = j;
- break;
- }
- }
- }
-
- return ch_no;
-}
-
-u8 process_p2p_group_negotation_req23a(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- struct rtw_adapter *padapter = pwdinfo->padapter;
- u8 result = P2P_STATUS_SUCCESS;
- u32 p2p_ielen = 0, wps_ielen = 0;
- u8 * ies;
- u32 ies_len;
- u8 *p2p_ie;
- u8 *wpsie;
- u16 wps_devicepassword_id = 0x0000;
- uint wps_devicepassword_id_len = 0;
-#ifdef CONFIG_8723AU_P2P
- u8 wfd_ie[ 128 ] = { 0x00 };
- u32 wfd_ielen = 0;
-#endif /* CONFIG_8723AU_P2P */
-
- if ((wpsie = rtw_get_wps_ie23a(pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen)))
- {
- /* Commented by Kurt 20120113 */
- /* If some device wants to do p2p handshake without sending prov_disc_req */
- /* We have to get peer_req_cm from here. */
- if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3))
- {
- rtw_get_wps_attr_content23a(wpsie, wps_ielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
- wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
-
- if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
- {
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
- }
- else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
- {
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
- }
- else
- {
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
- }
- }
- }
- else
- {
- DBG_8723A("[%s] WPS IE not Found!!\n", __func__);
- result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- return result;
- }
-
- if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO)
- {
- result = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INFOR_NOREADY);
- return result;
- }
-
- ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
- ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
-
- p2p_ie = rtw_get_p2p_ie23a(ies, ies_len, NULL, &p2p_ielen);
-
- if (!p2p_ie)
- {
- DBG_8723A("[%s] P2P IE not Found!!\n", __func__);
- result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- }
-
- while (p2p_ie)
- {
- u8 attr_content = 0x00;
- u32 attr_contentlen = 0;
- u8 ch_content[50] = { 0x00 };
- uint ch_cnt = 0;
- u8 peer_ch_list[50] = { 0x00 };
- u8 peer_ch_num = 0;
- u8 ch_list_inclusioned[50] = { 0x00 };
- u8 ch_num_inclusioned = 0;
- u16 cap_attr;
-
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
-
- /* Check P2P Capability ATTR */
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*)&attr_contentlen))
- cap_attr = le16_to_cpu(cap_attr);
-
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, &attr_content, &attr_contentlen))
- {
- DBG_8723A("[%s] GO Intent = %d, tie = %d\n", __func__, attr_content >> 1, attr_content & 0x01);
- pwdinfo->peer_intent = attr_content; /* include both intent and tie breaker values. */
-
- if (pwdinfo->intent == (pwdinfo->peer_intent >> 1))
- {
- /* Try to match the tie breaker value */
- if (pwdinfo->intent == P2P_MAX_INTENT)
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- result = P2P_STATUS_FAIL_BOTH_GOINTENT_15;
- }
- else
- {
- if (attr_content & 0x01)
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- }
- else
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- }
- }
- }
- else if (pwdinfo->intent > (pwdinfo->peer_intent >> 1))
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- }
- else
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- }
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- {
- /* Store the group id information. */
- memcpy(pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN);
- memcpy(pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
- }
- }
-
- attr_contentlen = 0;
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen))
- {
- if (attr_contentlen != ETH_ALEN)
- {
- memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
- }
- }
-
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, ch_content, &ch_cnt))
- {
- peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, ch_content, ch_cnt, peer_ch_list);
- ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
-
- if (ch_num_inclusioned == 0)
- {
- DBG_8723A("[%s] No common channel in channel list!\n", __func__);
- result = P2P_STATUS_FAIL_NO_COMMON_CH;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- break;
- }
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- {
- if (!rtw_p2p_is_channel_list_ok(pwdinfo->operating_channel,
- ch_list_inclusioned, ch_num_inclusioned))
- {
- {
- u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0;
- attr_contentlen = 0;
-
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
- {
- peer_operating_ch = operatingch_info[4];
- }
-
- if (rtw_p2p_is_channel_list_ok(peer_operating_ch,
- ch_list_inclusioned, ch_num_inclusioned))
- {
- /**
- * Change our operating channel as peer's for compatibility.
- */
- pwdinfo->operating_channel = peer_operating_ch;
- DBG_8723A("[%s] Change op ch to %02x as peer's\n", __func__, pwdinfo->operating_channel);
- }
- else
- {
- /* Take first channel of ch_list_inclusioned as operating channel */
- pwdinfo->operating_channel = ch_list_inclusioned[0];
- DBG_8723A("[%s] Change op ch to %02x\n", __func__, pwdinfo->operating_channel);
- }
- }
-
- }
- }
- }
-
- /* Get the next P2P IE */
- p2p_ie = rtw_get_p2p_ie23a(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
- }
-
-#ifdef CONFIG_8723AU_P2P
- /* Added by Albert 20110823 */
- /* Try to get the TCP port information when receiving the negotiation request. */
- if (rtw_get_wfd_ie(pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wfd_ie, &wfd_ielen))
- {
- u8 attr_content[ 10 ] = { 0x00 };
- u32 attr_contentlen = 0;
-
- DBG_8723A("[%s] WFD IE Found!!\n", __func__);
- rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
- if (attr_contentlen)
- {
- pwdinfo->wfd_info->peer_rtsp_ctrlport = get_unaligned_be16(attr_content + 2);
- DBG_8723A("[%s] Peer PORT NUM = %d\n", __func__, pwdinfo->wfd_info->peer_rtsp_ctrlport);
- }
- }
-#endif /* CONFIG_8723AU_P2P */
-
- return result;
-}
-
-u8 process_p2p_group_negotation_resp23a(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- struct rtw_adapter *padapter = pwdinfo->padapter;
- u8 result = P2P_STATUS_SUCCESS;
- u32 p2p_ielen, wps_ielen;
- u8 * ies;
- u32 ies_len;
- u8 * p2p_ie;
-#ifdef CONFIG_8723AU_P2P
- u8 wfd_ie[ 128 ] = { 0x00 };
- u32 wfd_ielen = 0;
-#endif /* CONFIG_8723AU_P2P */
-
- ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
- ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
-
- /* Be able to know which one is the P2P GO and which one is P2P client. */
-
- if (rtw_get_wps_ie23a(ies, ies_len, NULL, &wps_ielen))
- {
-
- }
- else
- {
- DBG_8723A("[%s] WPS IE not Found!!\n", __func__);
- result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- }
-
- p2p_ie = rtw_get_p2p_ie23a(ies, ies_len, NULL, &p2p_ielen);
- if (!p2p_ie)
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
- }
- else
- {
-
- u8 attr_content = 0x00;
- u32 attr_contentlen = 0;
- u8 operatingch_info[5] = { 0x00 };
- u8 groupid[ 38 ];
- u16 cap_attr;
- u8 peer_ch_list[50] = { 0x00 };
- u8 peer_ch_num = 0;
- u8 ch_list_inclusioned[50] = { 0x00 };
- u8 ch_num_inclusioned = 0;
-
- while (p2p_ie) /* Found the P2P IE. */
- {
-
- /* Check P2P Capability ATTR */
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*)&attr_contentlen))
- cap_attr = le16_to_cpu(cap_attr);
-
- rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
- if (attr_contentlen == 1)
- {
- DBG_8723A("[%s] Status = %d\n", __func__, attr_content);
- if (attr_content == P2P_STATUS_SUCCESS)
- {
- /* Do nothing. */
- }
- else
- {
- if (P2P_STATUS_FAIL_INFO_UNAVAILABLE == attr_content) {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INFOR_NOREADY);
- } else {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- }
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- result = attr_content;
- break;
- }
- }
-
- /* Try to get the peer's interface address */
- attr_contentlen = 0;
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen))
- {
- if (attr_contentlen != ETH_ALEN)
- {
- memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
- }
- }
-
- /* Try to get the peer's intent and tie breaker value. */
- attr_content = 0x00;
- attr_contentlen = 0;
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, &attr_content, &attr_contentlen))
- {
- DBG_8723A("[%s] GO Intent = %d, tie = %d\n", __func__, attr_content >> 1, attr_content & 0x01);
- pwdinfo->peer_intent = attr_content; /* include both intent and tie breaker values. */
-
- if (pwdinfo->intent == (pwdinfo->peer_intent >> 1))
- {
- /* Try to match the tie breaker value */
- if (pwdinfo->intent == P2P_MAX_INTENT)
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- result = P2P_STATUS_FAIL_BOTH_GOINTENT_15;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- }
- else
- {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
- if (attr_content & 0x01)
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- }
- else
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- }
- }
- }
- else if (pwdinfo->intent > (pwdinfo->peer_intent >> 1))
- {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- }
- else
- {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- }
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- {
- /* Store the group id information. */
- memcpy(pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN);
- memcpy(pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
-
- }
- }
-
- /* Try to get the operation channel information */
-
- attr_contentlen = 0;
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
- {
- DBG_8723A("[%s] Peer's operating channel = %d\n", __func__, operatingch_info[4]);
- pwdinfo->peer_operating_ch = operatingch_info[4];
- }
-
- /* Try to get the channel list information */
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, pwdinfo->channel_list_attr, &pwdinfo->channel_list_attr_len))
- {
- DBG_8723A("[%s] channel list attribute found, len = %d\n", __func__, pwdinfo->channel_list_attr_len);
-
- peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len, peer_ch_list);
- ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
-
- if (ch_num_inclusioned == 0)
- {
- DBG_8723A("[%s] No common channel in channel list!\n", __func__);
- result = P2P_STATUS_FAIL_NO_COMMON_CH;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- break;
- }
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- {
- if (!rtw_p2p_is_channel_list_ok(pwdinfo->operating_channel,
- ch_list_inclusioned, ch_num_inclusioned))
- {
- {
- u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0;
- attr_contentlen = 0;
-
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
- {
- peer_operating_ch = operatingch_info[4];
- }
-
- if (rtw_p2p_is_channel_list_ok(peer_operating_ch,
- ch_list_inclusioned, ch_num_inclusioned))
- {
- /**
- * Change our operating channel as peer's for compatibility.
- */
- pwdinfo->operating_channel = peer_operating_ch;
- DBG_8723A("[%s] Change op ch to %02x as peer's\n", __func__, pwdinfo->operating_channel);
- }
- else
- {
- /* Take first channel of ch_list_inclusioned as operating channel */
- pwdinfo->operating_channel = ch_list_inclusioned[0];
- DBG_8723A("[%s] Change op ch to %02x\n", __func__, pwdinfo->operating_channel);
- }
- }
-
- }
- }
-
- }
- else
- {
- DBG_8723A("[%s] channel list attribute not found!\n", __func__);
- }
-
- /* Try to get the group id information if peer is GO */
- attr_contentlen = 0;
- memset(groupid, 0x00, 38);
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen))
- {
- memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN);
- memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN);
- }
-
- /* Get the next P2P IE */
- p2p_ie = rtw_get_p2p_ie23a(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
- }
-
- }
-
-#ifdef CONFIG_8723AU_P2P
- /* Added by Albert 20111122 */
- /* Try to get the TCP port information when receiving the negotiation response. */
- if (rtw_get_wfd_ie(pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wfd_ie, &wfd_ielen))
- {
- u8 attr_content[ 10 ] = { 0x00 };
- u32 attr_contentlen = 0;
-
- DBG_8723A("[%s] WFD IE Found!!\n", __func__);
- rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
- if (attr_contentlen)
- {
- pwdinfo->wfd_info->peer_rtsp_ctrlport = get_unaligned_be16(attr_content + 2);
- DBG_8723A("[%s] Peer PORT NUM = %d\n", __func__, pwdinfo->wfd_info->peer_rtsp_ctrlport);
- }
- }
-#endif /* CONFIG_8723AU_P2P */
-
- return result;
-}
-
-u8 process_p2p_group_negotation_confirm23a(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- u8 * ies;
- u32 ies_len;
- u8 * p2p_ie;
- u32 p2p_ielen = 0;
- u8 result = P2P_STATUS_SUCCESS;
- ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
- ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
-
- p2p_ie = rtw_get_p2p_ie23a(ies, ies_len, NULL, &p2p_ielen);
- while (p2p_ie) /* Found the P2P IE. */
- {
- u8 attr_content = 0x00, operatingch_info[5] = { 0x00 };
- u8 groupid[ 38 ] = { 0x00 };
- u32 attr_contentlen = 0;
-
- pwdinfo->negotiation_dialog_token = 1;
- rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
- if (attr_contentlen == 1)
- {
- DBG_8723A("[%s] Status = %d\n", __func__, attr_content);
- result = attr_content;
-
- if (attr_content == P2P_STATUS_SUCCESS)
- {
- del_timer_sync(&pwdinfo->restore_p2p_state_timer);
-
- /* Commented by Albert 20100911 */
- /* Todo: Need to handle the case which both Intents are the same. */
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
- if ((pwdinfo->intent) > (pwdinfo->peer_intent >> 1))
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- }
- else if ((pwdinfo->intent) < (pwdinfo->peer_intent >> 1))
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- }
- else
- {
- /* Have to compare the Tie Breaker */
- if (pwdinfo->peer_intent & 0x01)
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- }
- else
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- }
- }
- }
- else
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- break;
- }
- }
-
- /* Try to get the group id information */
- attr_contentlen = 0;
- memset(groupid, 0x00, 38);
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen))
- {
- DBG_8723A("[%s] Ssid = %s, ssidlen = %zu\n", __func__, &groupid[ETH_ALEN], strlen(&groupid[ETH_ALEN]));
- memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN);
- memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN);
- }
-
- attr_contentlen = 0;
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
- {
- DBG_8723A("[%s] Peer's operating channel = %d\n", __func__, operatingch_info[4]);
- pwdinfo->peer_operating_ch = operatingch_info[4];
- }
-
- /* Get the next P2P IE */
- p2p_ie = rtw_get_p2p_ie23a(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
-
- }
-
- return result;
-}
-
-u8 process_p2p_presence_req23a(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- u8 *frame_body;
- u8 dialogToken = 0;
- u8 status = P2P_STATUS_SUCCESS;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) pframe;
-
- frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
-
- dialogToken = frame_body[6];
-
- /* todo: check NoA attribute */
-
- issue_p2p_presence_resp(pwdinfo, hdr->addr2, status, dialogToken);
-
- return true;
-}
-
-static void find_phase_handler(struct rtw_adapter *padapter)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct cfg80211_ssid ssid;
- u8 _status = 0;
-
-
-
- memset((unsigned char*)&ssid, 0, sizeof(struct cfg80211_ssid));
- memcpy(ssid.ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);
- ssid.ssid_len = P2P_WILDCARD_SSID_LEN;
-
- rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
-
- spin_lock_bh(&pmlmepriv->lock);
- _status = rtw_sitesurvey_cmd23a(padapter, &ssid, 1, NULL, 0);
- spin_unlock_bh(&pmlmepriv->lock);
-
-
-}
-
-void p2p_concurrent_handler(struct rtw_adapter* padapter);
-
-static void restore_p2p_state_handler(struct rtw_adapter *padapter)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
- /* In the P2P client mode, the driver should not switch back to its listen channel */
- /* because this P2P client should stay at the operating channel of P2P GO. */
- set_channel_bwmode23a(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- }
-}
-
-static void pre_tx_invitereq_handler(struct rtw_adapter *padapter)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 val8 = 1;
-
- set_channel_bwmode23a(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
- issue23a_probereq_p2p(padapter, NULL);
- mod_timer(&pwdinfo->pre_tx_scan_timer,
- jiffies + msecs_to_jiffies(P2P_TX_PRESCAN_TIMEOUT));
-
-
-}
-
-static void pre_tx_provdisc_handler(struct rtw_adapter *padapter)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 val8 = 1;
-
-
- set_channel_bwmode23a(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
- issue23a_probereq_p2p(padapter, NULL);
- mod_timer(&pwdinfo->pre_tx_scan_timer,
- jiffies + msecs_to_jiffies(P2P_TX_PRESCAN_TIMEOUT));
-
-
-}
-
-static void pre_tx_negoreq_handler(struct rtw_adapter *padapter)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 val8 = 1;
-
-
- set_channel_bwmode23a(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
- issue23a_probereq_p2p(padapter, NULL);
- mod_timer(&pwdinfo->pre_tx_scan_timer,
- jiffies + msecs_to_jiffies(P2P_TX_PRESCAN_TIMEOUT));
-
-
-}
-
-static void ro_ch_handler(struct rtw_adapter *padapter)
-{
- struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- if (pcfg80211_wdinfo->restore_channel != pmlmeext->cur_channel) {
- if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
- pmlmeext->cur_channel = pcfg80211_wdinfo->restore_channel;
-
- set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
- HAL_PRIME_CHNL_OFFSET_DONT_CARE,
- HT_CHANNEL_WIDTH_20);
- }
-
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
-
- pcfg80211_wdinfo->is_ro_ch = false;
-
- DBG_8723A("cfg80211_remain_on_channel_expired\n");
-
- rtw_cfg80211_remain_on_channel_expired(padapter,
- pcfg80211_wdinfo->remain_on_ch_cookie,
- &pcfg80211_wdinfo->remain_on_ch_channel,
- pcfg80211_wdinfo->remain_on_ch_type, GFP_KERNEL);
-}
-
-static void ro_ch_timer_process (unsigned long data)
-{
- struct rtw_adapter *adapter = (struct rtw_adapter *)data;
-
- p2p_protocol_wk_cmd23a(adapter, P2P_RO_CH_WK);
-}
-
-#ifdef CONFIG_8723AU_P2P
-void rtw_append_wfd_ie(struct rtw_adapter *padapter, u8 *buf, u32* len)
-{
- unsigned char *frame_body;
- u8 category, action, OUI_Subtype, dialogToken = 0;
- u32 wfdielen = 0;
-
- frame_body = (unsigned char *)(buf + sizeof(struct ieee80211_hdr_3addr));
- category = frame_body[0];
-
- if (category == WLAN_CATEGORY_PUBLIC) {
- action = frame_body[1];
- if (action == ACT_PUBLIC_VENDOR &&
- !memcmp(frame_body+2, P2P_OUI23A, 4)) {
- OUI_Subtype = frame_body[6];
- dialogToken = frame_body[7];
- switch (OUI_Subtype)/* OUI Subtype */ {
- case P2P_GO_NEGO_REQ:
- wfdielen = build_nego_req_wfd_ie(&padapter->wdinfo, buf + (*len));
- (*len) += wfdielen;
- break;
- case P2P_GO_NEGO_RESP:
- wfdielen = build_nego_resp_wfd_ie(&padapter->wdinfo, buf + (*len));
- (*len) += wfdielen;
- break;
- case P2P_GO_NEGO_CONF:
- wfdielen = build_nego_confirm_wfd_ie(&padapter->wdinfo, buf + (*len));
- (*len) += wfdielen;
- break;
- case P2P_INVIT_REQ:
- wfdielen = build_invitation_req_wfd_ie(&padapter->wdinfo, buf + (*len));
- (*len) += wfdielen;
- break;
- case P2P_INVIT_RESP:
- wfdielen = build_invitation_resp_wfd_ie(&padapter->wdinfo, buf + (*len));
- (*len) += wfdielen;
- break;
- case P2P_DEVDISC_REQ:
- break;
- case P2P_DEVDISC_RESP:
- break;
- case P2P_PROVISION_DISC_REQ:
- wfdielen = build_provdisc_req_wfd_ie(&padapter->wdinfo, buf + (*len));
- (*len) += wfdielen;
- break;
- case P2P_PROVISION_DISC_RESP:
- wfdielen = build_provdisc_resp_wfd_ie(&padapter->wdinfo, buf + (*len));
- (*len) += wfdielen;
- break;
- default:
- break;
- }
- }
- } else if (category == WLAN_CATEGORY_VENDOR_SPECIFIC) {
- OUI_Subtype = frame_body[5];
- dialogToken = frame_body[6];
- } else {
- DBG_8723A("%s, action frame category =%d\n", __func__, category);
- }
-}
-#endif
-
-int rtw_p2p_check_frames(struct rtw_adapter *padapter, const u8 *buf, u32 len, u8 tx)
-{
- int is_p2p_frame = (-1);
- unsigned char *frame_body;
- u8 category, action, OUI_Subtype, dialogToken = 0;
- u8 *p2p_ie = NULL;
- uint p2p_ielen = 0;
- struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
-
- frame_body = (unsigned char *)(buf + sizeof(struct ieee80211_hdr_3addr));
- category = frame_body[0];
- /* just for check */
- if (category == WLAN_CATEGORY_PUBLIC)
- {
- action = frame_body[1];
- if (action == ACT_PUBLIC_VENDOR &&
- !memcmp(frame_body+2, P2P_OUI23A, 4)) {
- OUI_Subtype = frame_body[6];
- dialogToken = frame_body[7];
- is_p2p_frame = OUI_Subtype;
- p2p_ie = rtw_get_p2p_ie23a(
- (u8 *)buf+sizeof(struct ieee80211_hdr_3addr)+_PUBLIC_ACTION_IE_OFFSET_,
- len-sizeof(struct ieee80211_hdr_3addr)-_PUBLIC_ACTION_IE_OFFSET_,
- NULL, &p2p_ielen);
-
- switch (OUI_Subtype) {/* OUI Subtype */
- u8 *cont;
- uint cont_len;
- case P2P_GO_NEGO_REQ:
- DBG_8723A("RTW_%s:P2P_GO_NEGO_REQ, dialogToken =%d\n", (tx == true)?"Tx":"Rx", dialogToken);
- break;
- case P2P_GO_NEGO_RESP:
- cont = rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len);
- DBG_8723A("RTW_%s:P2P_GO_NEGO_RESP, dialogToken =%d, status:%d\n", (tx == true)?"Tx":"Rx", dialogToken, cont?*cont:-1);
-
- if (!tx)
- pwdev_priv->provdisc_req_issued = false;
- break;
- case P2P_GO_NEGO_CONF:
- cont = rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len);
- DBG_8723A("RTW_%s:P2P_GO_NEGO_CONF, dialogToken =%d, status:%d\n",
- (tx == true)?"Tx":"Rx", dialogToken, cont?*cont:-1);
- break;
- case P2P_INVIT_REQ:
- {
- struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info;
- int flags = -1;
- int op_ch = 0;
-
- if ((cont = rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, NULL, &cont_len)))
- flags = *cont;
- if ((cont = rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
- op_ch = *(cont+4);
-
- if (invit_info->token != dialogToken)
- rtw_wdev_invit_info_init(invit_info);
-
- invit_info->token = dialogToken;
- invit_info->flags = (flags ==-1) ? 0x0 : flags;
- invit_info->req_op_ch = op_ch;
-
- DBG_8723A("RTW_%s:P2P_INVIT_REQ, dialogToken =%d, flags:0x%02x, op_ch:%d\n",
- (tx) ? "Tx" : "Rx", dialogToken, flags, op_ch);
- break;
- }
- case P2P_INVIT_RESP:
- {
- struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info;
- int status = -1;
- int op_ch = 0;
-
- if ((cont = rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len)))
- status = *cont;
- if ((cont = rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
- op_ch = *(cont+4);
-
- if (invit_info->token != dialogToken) {
- rtw_wdev_invit_info_init(invit_info);
- } else {
- invit_info->token = 0;
- invit_info->status = (status ==-1) ? 0xff : status;
- invit_info->rsp_op_ch = op_ch;
- }
-
- DBG_8723A("RTW_%s:P2P_INVIT_RESP, dialogToken =%d, status:%d, op_ch:%d\n",
- (tx == true)?"Tx":"Rx", dialogToken, status, op_ch);
- break;
- }
- case P2P_DEVDISC_REQ:
- DBG_8723A("RTW_%s:P2P_DEVDISC_REQ, dialogToken =%d\n", (tx == true)?"Tx":"Rx", dialogToken);
- break;
- case P2P_DEVDISC_RESP:
- cont = rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len);
- DBG_8723A("RTW_%s:P2P_DEVDISC_RESP, dialogToken =%d, status:%d\n", (tx == true)?"Tx":"Rx", dialogToken, cont?*cont:-1);
- break;
- case P2P_PROVISION_DISC_REQ:
- {
- size_t frame_body_len = len - sizeof(struct ieee80211_hdr_3addr);
- u8 *p2p_ie;
- uint p2p_ielen = 0;
- uint contentlen = 0;
-
- DBG_8723A("RTW_%s:P2P_PROVISION_DISC_REQ, dialogToken =%d\n", (tx == true)?"Tx":"Rx", dialogToken);
-
- pwdev_priv->provdisc_req_issued = false;
-
- p2p_ie = rtw_get_p2p_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_,
- frame_body_len - _PUBLIC_ACTION_IE_OFFSET_,
- NULL, &p2p_ielen);
- if (p2p_ie) {
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, NULL, &contentlen))
- pwdev_priv->provdisc_req_issued = false;/* case: p2p_client join p2p GO */
- else
- pwdev_priv->provdisc_req_issued = true;/* case: p2p_devices connection before Nego req. */
- }
- }
- break;
- case P2P_PROVISION_DISC_RESP:
- DBG_8723A("RTW_%s:P2P_PROVISION_DISC_RESP, dialogToken =%d\n", (tx == true)?"Tx":"Rx", dialogToken);
- break;
- default:
- DBG_8723A("RTW_%s:OUI_Subtype =%d, dialogToken =%d\n", (tx == true)?"Tx":"Rx", OUI_Subtype, dialogToken);
- break;
- }
-
- }
-
- }
- else if (category == WLAN_CATEGORY_VENDOR_SPECIFIC)
- {
- OUI_Subtype = frame_body[5];
- dialogToken = frame_body[6];
-
- is_p2p_frame = OUI_Subtype;
-
- switch (OUI_Subtype) {
- case P2P_NOTICE_OF_ABSENCE:
- DBG_8723A("RTW_%s:P2P_NOTICE_OF_ABSENCE, dialogToken =%d\n", (tx == true)?"TX":"RX", dialogToken);
- break;
- case P2P_PRESENCE_REQUEST:
- DBG_8723A("RTW_%s:P2P_PRESENCE_REQUEST, dialogToken =%d\n", (tx == true)?"TX":"RX", dialogToken);
- break;
- case P2P_PRESENCE_RESPONSE:
- DBG_8723A("RTW_%s:P2P_PRESENCE_RESPONSE, dialogToken =%d\n", (tx == true)?"TX":"RX", dialogToken);
- break;
- case P2P_GO_DISC_REQUEST:
- DBG_8723A("RTW_%s:P2P_GO_DISC_REQUEST, dialogToken =%d\n", (tx == true)?"TX":"RX", dialogToken);
- break;
- default:
- DBG_8723A("RTW_%s:OUI_Subtype =%d, dialogToken =%d\n", (tx == true)?"TX":"RX", OUI_Subtype, dialogToken);
- break;
- }
-
- } else {
- DBG_8723A("RTW_%s:action frame category =%d\n", (tx == true)?"TX":"RX", category);
- }
- return is_p2p_frame;
-}
-
-void rtw_init_cfg80211_wifidirect_info(struct rtw_adapter *padapter)
-{
- struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
-
- memset(pcfg80211_wdinfo, 0x00, sizeof(struct cfg80211_wifidirect_info));
-
- setup_timer(&pcfg80211_wdinfo->remain_on_ch_timer,
- ro_ch_timer_process, (unsigned long)padapter);
-}
-
-void p2p_protocol_wk_hdl23a(struct rtw_adapter *padapter, int intCmdType)
-{
- switch (intCmdType) {
- case P2P_FIND_PHASE_WK:
- find_phase_handler(padapter);
- break;
- case P2P_RESTORE_STATE_WK:
- restore_p2p_state_handler(padapter);
- break;
- case P2P_PRE_TX_PROVDISC_PROCESS_WK:
- pre_tx_provdisc_handler(padapter);
- break;
- case P2P_PRE_TX_INVITEREQ_PROCESS_WK:
- pre_tx_invitereq_handler(padapter);
- break;
- case P2P_PRE_TX_NEGOREQ_PROCESS_WK:
- pre_tx_negoreq_handler(padapter);
- break;
- case P2P_RO_CH_WK:
- ro_ch_handler(padapter);
- break;
- }
-}
-
-#ifdef CONFIG_8723AU_P2P
-void process_p2p_ps_ie23a(struct rtw_adapter *padapter, u8 *IEs, u32 IELength)
-{
- u8 * ies;
- u32 ies_len;
- u8 * p2p_ie;
- u32 p2p_ielen = 0;
- u8 noa_attr[MAX_P2P_IE_LEN] = { 0x00 };/* NoA length should be n*(13) + 2 */
- u32 attr_contentlen = 0;
-
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 find_p2p = false, find_p2p_ps = false;
- u8 noa_offset, noa_num, noa_index;
-
-
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- {
- return;
- }
- if (IELength <= _BEACON_IE_OFFSET_)
- return;
-
- ies = IEs + _BEACON_IE_OFFSET_;
- ies_len = IELength - _BEACON_IE_OFFSET_;
-
- p2p_ie = rtw_get_p2p_ie23a(ies, ies_len, NULL, &p2p_ielen);
-
- while(p2p_ie)
- {
- find_p2p = true;
- /* Get Notice of Absence IE. */
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_NOA, noa_attr, &attr_contentlen))
- {
- find_p2p_ps = true;
- noa_index = noa_attr[0];
-
- if ((pwdinfo->p2p_ps_mode == P2P_PS_NONE) ||
- (noa_index != pwdinfo->noa_index))/* if index change, driver should reconfigure related setting. */
- {
- pwdinfo->noa_index = noa_index;
- pwdinfo->opp_ps = noa_attr[1] >> 7;
- pwdinfo->ctwindow = noa_attr[1] & 0x7F;
-
- noa_offset = 2;
- noa_num = 0;
- /* NoA length should be n*(13) + 2 */
- if (attr_contentlen > 2)
- {
- while(noa_offset < attr_contentlen)
- {
- /* memcpy(&wifidirect_info->noa_count[noa_num], &noa_attr[noa_offset], 1); */
- pwdinfo->noa_count[noa_num] = noa_attr[noa_offset];
- noa_offset += 1;
-
- memcpy(&pwdinfo->noa_duration[noa_num], &noa_attr[noa_offset], 4);
- noa_offset += 4;
-
- memcpy(&pwdinfo->noa_interval[noa_num], &noa_attr[noa_offset], 4);
- noa_offset += 4;
-
- memcpy(&pwdinfo->noa_start_time[noa_num], &noa_attr[noa_offset], 4);
- noa_offset += 4;
-
- noa_num++;
- }
- }
- pwdinfo->noa_num = noa_num;
-
- if (pwdinfo->opp_ps == 1)
- {
- pwdinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
- /* driver should wait LPS for entering CTWindow */
- if (padapter->pwrctrlpriv.bFwCurrentInPSMode == true)
- {
- p2p_ps_wk_cmd23a(padapter, P2P_PS_ENABLE, 1);
- }
- }
- else if (pwdinfo->noa_num > 0)
- {
- pwdinfo->p2p_ps_mode = P2P_PS_NOA;
- p2p_ps_wk_cmd23a(padapter, P2P_PS_ENABLE, 1);
- }
- else if (pwdinfo->p2p_ps_mode > P2P_PS_NONE)
- {
- p2p_ps_wk_cmd23a(padapter, P2P_PS_DISABLE, 1);
- }
- }
-
- break; /* find target, just break. */
- }
-
- /* Get the next P2P IE */
- p2p_ie = rtw_get_p2p_ie23a(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
-
- }
-
- if (find_p2p == true)
- {
- if ((pwdinfo->p2p_ps_mode > P2P_PS_NONE) && (find_p2p_ps == false))
- {
- p2p_ps_wk_cmd23a(padapter, P2P_PS_DISABLE, 1);
- }
- }
-
-
-}
-
-void p2p_ps_wk_hdl23a(struct rtw_adapter *padapter, u8 p2p_ps_state)
-{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
-
-
- /* Pre action for p2p state */
- switch (p2p_ps_state)
- {
- case P2P_PS_DISABLE:
- pwdinfo->p2p_ps_state = p2p_ps_state;
-
- rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
-
- pwdinfo->noa_index = 0;
- pwdinfo->ctwindow = 0;
- pwdinfo->opp_ps = 0;
- pwdinfo->noa_num = 0;
- pwdinfo->p2p_ps_mode = P2P_PS_NONE;
- if (padapter->pwrctrlpriv.bFwCurrentInPSMode == true)
- {
- if (pwrpriv->smart_ps == 0)
- {
- pwrpriv->smart_ps = 2;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)&padapter->pwrctrlpriv.pwr_mode);
- }
- }
- break;
- case P2P_PS_ENABLE:
- if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
- pwdinfo->p2p_ps_state = p2p_ps_state;
-
- if (pwdinfo->ctwindow > 0)
- {
- if (pwrpriv->smart_ps != 0)
- {
- pwrpriv->smart_ps = 0;
- DBG_8723A("%s(): Enter CTW, change SmartPS\n", __func__);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)&padapter->pwrctrlpriv.pwr_mode);
- }
- }
- rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
- }
- break;
- case P2P_PS_SCAN:
- case P2P_PS_SCAN_DONE:
- case P2P_PS_ALLSTASLEEP:
- if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
- pwdinfo->p2p_ps_state = p2p_ps_state;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
- }
- break;
- default:
- break;
- }
-
-
-}
-
-u8 p2p_ps_wk_cmd23a(struct rtw_adapter*padapter, u8 p2p_ps_state, u8 enqueue)
-{
- struct cmd_obj *ph2c;
- struct drvextra_cmd_parm *pdrvextra_cmd_parm;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
-
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return res;
-
- if (enqueue) {
- ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
- GFP_ATOMIC);
- if (!ph2c) {
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)
- kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC);
- if (pdrvextra_cmd_parm == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm->ec_id = P2P_PS_WK_CID;
- pdrvextra_cmd_parm->type_size = p2p_ps_state;
- 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
- {
- p2p_ps_wk_hdl23a(padapter, p2p_ps_state);
- }
-
-exit:
-
-
-
- return res;
-}
-#endif /* CONFIG_8723AU_P2P */
-
-static void reset_ch_sitesurvey_timer_process(unsigned long data)
-{
- struct rtw_adapter *adapter = (struct rtw_adapter *)data;
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
-
- DBG_8723A("[%s] In\n", __func__);
- /* Reset the operation channel information */
- pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
- pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
-}
-
-static void reset_ch_sitesurvey_timer_process2(unsigned long data)
-{
- struct rtw_adapter *adapter = (struct rtw_adapter *)data;
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
-
- DBG_8723A("[%s] In\n", __func__);
- /* Reset the operation channel information */
- pwdinfo->p2p_info.operation_ch[0] = 0;
- pwdinfo->p2p_info.scan_op_ch_only = 0;
-}
-
-static void restore_p2p_state_timer_process (unsigned long data)
-{
- struct rtw_adapter *adapter = (struct rtw_adapter *)data;
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
-
- p2p_protocol_wk_cmd23a(adapter, P2P_RESTORE_STATE_WK);
-}
-
-static void pre_tx_scan_timer_process (unsigned long data)
-{
- struct rtw_adapter *adapter = (struct rtw_adapter *)data;
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
-
- spin_lock_bh(&pmlmepriv->lock);
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
- {
- if (true == pwdinfo->tx_prov_disc_info.benable) /* the provision discovery request frame is trigger to send or not */
- {
- p2p_protocol_wk_cmd23a(adapter, P2P_PRE_TX_PROVDISC_PROCESS_WK);
- /* issue23a_probereq_p2p(adapter, NULL); */
- /* _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); */
- }
- }
- else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
- {
- if (true == pwdinfo->nego_req_info.benable)
- {
- p2p_protocol_wk_cmd23a(adapter, P2P_PRE_TX_NEGOREQ_PROCESS_WK);
- }
- }
- else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ))
- {
- if (true == pwdinfo->invitereq_info.benable)
- {
- p2p_protocol_wk_cmd23a(adapter, P2P_PRE_TX_INVITEREQ_PROCESS_WK);
- }
- }
- else
- {
- DBG_8723A("[%s] p2p_state is %d, ignore!!\n", __func__, rtw_p2p_state(pwdinfo));
- }
-
- spin_unlock_bh(&pmlmepriv->lock);
-}
-
-static void find_phase_timer_process (unsigned long data)
-{
- struct rtw_adapter *adapter = (struct rtw_adapter *)data;
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
-
- adapter->wdinfo.find_phase_state_exchange_cnt++;
-
- p2p_protocol_wk_cmd23a(adapter, P2P_FIND_PHASE_WK);
-}
-
-void reset_global_wifidirect_info23a(struct rtw_adapter *padapter)
-{
- struct wifidirect_info *pwdinfo;
-
- pwdinfo = &padapter->wdinfo;
- pwdinfo->persistent_supported = 0;
- pwdinfo->session_available = true;
- pwdinfo->wfd_tdls_enable = 0;
- pwdinfo->wfd_tdls_weaksec = 0;
-}
-
-#ifdef CONFIG_8723AU_P2P
-int rtw_init_wifi_display_info(struct rtw_adapter* padapter)
-{
- int res = _SUCCESS;
- struct wifi_display_info *pwfd_info = &padapter->wfd_info;
-
- /* Used in P2P and TDLS */
- pwfd_info->rtsp_ctrlport = 554;
- pwfd_info->peer_rtsp_ctrlport = 0; /* Reset to 0 */
- pwfd_info->wfd_enable = false;
- pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;
- pwfd_info->scan_result_type = SCAN_RESULT_P2P_ONLY;
-
- /* Used in P2P */
- pwfd_info->peer_session_avail = true;
- pwfd_info->wfd_pc = false;
-
- /* Used in TDLS */
- memset(pwfd_info->ip_address, 0x00, 4);
- memset(pwfd_info->peer_ip_address, 0x00, 4);
- return res;
-}
-#endif /* CONFIG_8723AU_P2P */
-
-void rtw_init_wifidirect_timers23a(struct rtw_adapter* padapter)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- setup_timer(&pwdinfo->find_phase_timer, find_phase_timer_process,
- (unsigned long)padapter);
- setup_timer(&pwdinfo->restore_p2p_state_timer,
- restore_p2p_state_timer_process, (unsigned long)padapter);
- setup_timer(&pwdinfo->pre_tx_scan_timer, pre_tx_scan_timer_process,
- (unsigned long)padapter);
- setup_timer(&pwdinfo->reset_ch_sitesurvey,
- reset_ch_sitesurvey_timer_process, (unsigned long)padapter);
- setup_timer(&pwdinfo->reset_ch_sitesurvey2,
- reset_ch_sitesurvey_timer_process2,
- (unsigned long)padapter);
-}
-
-void rtw_init_wifidirect_addrs23a(struct rtw_adapter* padapter, u8 *dev_addr, u8 *iface_addr)
-{
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- /*init device&interface address */
- if (dev_addr) {
- memcpy(pwdinfo->device_addr, dev_addr, ETH_ALEN);
- }
- if (iface_addr) {
- memcpy(pwdinfo->interface_addr, iface_addr, ETH_ALEN);
- }
-#endif
-}
-
-void init_wifidirect_info23a(struct rtw_adapter *padapter, enum P2P_ROLE role)
-{
- struct wifidirect_info *pwdinfo;
-#ifdef CONFIG_8723AU_P2P
- struct wifi_display_info *pwfd_info = &padapter->wfd_info;
-#endif
-
- pwdinfo = &padapter->wdinfo;
-
- pwdinfo->padapter = padapter;
-
- /* 1, 6, 11 are the social channel defined in the WiFi Direct specification. */
- pwdinfo->social_chan[0] = 1;
- pwdinfo->social_chan[1] = 6;
- pwdinfo->social_chan[2] = 11;
- pwdinfo->social_chan[3] = 0; /* channel 0 for scanning ending in site survey function. */
-
- /* Use the channel 11 as the listen channel */
- pwdinfo->listen_channel = 11;
-
- if (role == P2P_ROLE_DEVICE)
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
- pwdinfo->intent = 1;
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_LISTEN);
- }
- else if (role == P2P_ROLE_CLIENT)
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- pwdinfo->intent = 1;
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
- }
- else if (role == P2P_ROLE_GO)
- {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- pwdinfo->intent = 15;
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
- }
-
-/* Use the OFDM rate in the P2P probe response frame. (6(B), 9(B), 12, 18, 24, 36, 48, 54) */
- pwdinfo->support_rate[0] = 0x8c; /* 6(B) */
- pwdinfo->support_rate[1] = 0x92; /* 9(B) */
- pwdinfo->support_rate[2] = 0x18; /* 12 */
- pwdinfo->support_rate[3] = 0x24; /* 18 */
- pwdinfo->support_rate[4] = 0x30; /* 24 */
- pwdinfo->support_rate[5] = 0x48; /* 36 */
- pwdinfo->support_rate[6] = 0x60; /* 48 */
- pwdinfo->support_rate[7] = 0x6c; /* 54 */
-
- memcpy((void*) pwdinfo->p2p_wildcard_ssid, "DIRECT-", 7);
-
- memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);
- pwdinfo->device_name_len = 0;
-
- memset(&pwdinfo->invitereq_info, 0x00, sizeof(struct tx_invite_req_info));
- pwdinfo->invitereq_info.token = 3; /* Token used for P2P invitation request frame. */
-
- memset(&pwdinfo->inviteresp_info, 0x00, sizeof(struct tx_invite_resp_info));
- pwdinfo->inviteresp_info.token = 0;
-
- pwdinfo->profileindex = 0;
- memset(&pwdinfo->profileinfo[ 0 ], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);
-
- rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
-
- pwdinfo->listen_dwell = (u8) ((jiffies % 3) + 1);
- /* DBG_8723A("[%s] listen_dwell time is %d00ms\n", __func__, pwdinfo->listen_dwell); */
-
- memset(&pwdinfo->tx_prov_disc_info, 0x00, sizeof(struct tx_provdisc_req_info));
- pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_NONE;
-
- memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));
-
- pwdinfo->device_password_id_for_nego = WPS_DPID_PBC;
- pwdinfo->negotiation_dialog_token = 1;
-
- memset(pwdinfo->nego_ssid, 0x00, IEEE80211_MAX_SSID_LEN);
- pwdinfo->nego_ssidlen = 0;
-
- pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
-#ifdef CONFIG_8723AU_P2P
- pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC;
- pwdinfo->wfd_info = pwfd_info;
-#else
- pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC | WPS_CONFIG_METHOD_KEYPAD;
-#endif /* CONFIG_8723AU_P2P */
- pwdinfo->channel_list_attr_len = 0;
- memset(pwdinfo->channel_list_attr, 0x00, 100);
-
- memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, 0x00, 4);
- memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, '0', 3);
- memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
- pwdinfo->wfd_tdls_enable = 0;
- memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
- memset(pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN);
-
- pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
- pwdinfo->rx_invitereq_info.operation_ch[1] = 0; /* Used to indicate the scan end in site survey function */
- pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
- pwdinfo->p2p_info.operation_ch[0] = 0;
- pwdinfo->p2p_info.operation_ch[1] = 0; /* Used to indicate the scan end in site survey function */
- pwdinfo->p2p_info.scan_op_ch_only = 0;
-}
-
-int rtw_p2p_enable23a(struct rtw_adapter *padapter, enum P2P_ROLE role)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- int ret = _SUCCESS;
-
- if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT ||
- role == P2P_ROLE_GO) {
- /* leave IPS/Autosuspend */
- if (_FAIL == rtw_pwr_wakeup(padapter)) {
- ret = _FAIL;
- goto exit;
- }
-
- /* Added by Albert 2011/03/22 */
- /* In the P2P mode, the driver should not support the b mode. */
- /* So, the Tx packet shouldn't use the CCK rate */
- update_tx_basic_rate23a(padapter, WIRELESS_11AGN);
-
- /* Enable P2P function */
- init_wifidirect_info23a(padapter, role);
-
- rtw_hal_set_odm_var23a(padapter, HAL_ODM_P2P_STATE, NULL, true);
- #ifdef CONFIG_8723AU_P2P
- rtw_hal_set_odm_var23a(padapter, HAL_ODM_WIFI_DISPLAY_STATE, NULL, true);
- #endif
-
- }
- else if (role == P2P_ROLE_DISABLE)
- {
- if (_FAIL == rtw_pwr_wakeup(padapter)) {
- ret = _FAIL;
- goto exit;
- }
-
- /* Disable P2P function */
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- {
- del_timer_sync(&pwdinfo->find_phase_timer);
- del_timer_sync(&pwdinfo->restore_p2p_state_timer);
- del_timer_sync(&pwdinfo->pre_tx_scan_timer);
- del_timer_sync(&pwdinfo->reset_ch_sitesurvey);
- del_timer_sync(&pwdinfo->reset_ch_sitesurvey2);
- reset_ch_sitesurvey_timer_process((unsigned long)padapter);
- reset_ch_sitesurvey_timer_process2((unsigned long)padapter);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DISABLE);
- memset(&pwdinfo->rx_prov_disc_info, 0x00, sizeof(struct rx_provdisc_req_info));
- }
-
- rtw_hal_set_odm_var23a(padapter, HAL_ODM_P2P_STATE, NULL, false);
- #ifdef CONFIG_8723AU_P2P
- rtw_hal_set_odm_var23a(padapter, HAL_ODM_WIFI_DISPLAY_STATE, NULL, false);
- #endif
-
- /* Restore to initial setting. */
- update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
- }
-
-exit:
- return ret;
-}
-
-#endif /* CONFIG_8723AU_P2P */
#include <osdep_service.h>
#include <drv_types.h>
#include <osdep_intf.h>
+#include <rtl8723a_cmd.h>
#ifdef CONFIG_8723AU_BT_COEXIST
#include <rtl8723a_hal.h>
struct rtw_adapter *buddy = adapter->pbuddy_adapter;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
struct xmit_priv *pxmit_priv = &adapter->xmitpriv;
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
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)
- || !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
- ) {
+ 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;
}
/* consider buddy, if exist */
if (buddy) {
struct mlme_priv *b_pmlmepriv = &buddy->mlmepriv;
- struct wifidirect_info *b_pwdinfo = &buddy->wdinfo;
-
- if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR)
- || check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS)
- || check_fwstate(b_pmlmepriv, WIFI_AP_STATE)
- || check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)
- || !rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE)
- ) {
+
+ if (check_fwstate(b_pmlmepriv,
+ WIFI_ASOC_STATE|WIFI_SITE_MONITOR) ||
+ check_fwstate(b_pmlmepriv,
+ WIFI_UNDER_LINKING|WIFI_UNDER_WPS) ||
+ check_fwstate(b_pmlmepriv, WIFI_AP_STATE) ||
+ check_fwstate(b_pmlmepriv,
+ WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)) {
goto exit;
}
}
pwrpriv->rpwm = pslv;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
+ rtl8723a_set_rpwm(padapter, rpwm);
pwrpriv->tog += 0x80;
pwrpriv->cpwm = pslv;
}
-u8 PS_RDY_CHECK(struct rtw_adapter * padapter)
+static u8 PS_RDY_CHECK(struct rtw_adapter * padapter)
{
unsigned long delta_time;
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
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;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif /* CONFIG_8723AU_P2P */
-
-
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
("%s: PowerMode =%d Smart_PS =%d\n",
}
if (ps_mode == PS_MODE_ACTIVE) {
-#ifdef CONFIG_8723AU_P2P
- if (pwdinfo->opp_ps == 0)
-#endif /* CONFIG_8723AU_P2P */
- {
- DBG_8723A("rtw_set_ps_mode23a: Leave 802.11 power save\n");
+ DBG_8723A("rtw_set_ps_mode23a: Leave 802.11 power save\n");
- pwrpriv->pwr_mode = ps_mode;
- rtw_set_rpwm23a(padapter, PS_STATE_S4);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
- pwrpriv->bFwCurrentInPSMode = false;
- }
- }
- else
- {
+ 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)
#ifdef CONFIG_8723AU_BT_COEXIST
|| (BT_1Ant(padapter) == true)
#endif
- )
- {
+ ) {
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;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
-
-#ifdef CONFIG_8723AU_P2P
- /* Set CTWindow after LPS */
- if (pwdinfo->opp_ps == 1)
- p2p_ps_wk_cmd23a(padapter, P2P_PS_ENABLE, 0);
-#endif /* CONFIG_8723AU_P2P */
+ rtl8723a_set_FwPwrMode_cmd(padapter, ps_mode);
rtw_set_rpwm23a(padapter, PS_STATE_S2);
}
}
-
-
}
/*
while (1)
{
- rtw23a_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake);
- if (true == bAwake)
+ bAwake = rtl8723a_get_fwlps_rf_on(padapter);
+ if (bAwake == true)
break;
- if (true == padapter->bSurpriseRemoved)
- {
+ if (padapter->bSurpriseRemoved == true) {
err = -2;
DBG_8723A("%s: device surprise removed!!\n", __func__);
break;
/* DBG_8723A("%s.....\n", __func__); */
if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
{ /* connect */
-#ifdef CONFIG_8723AU_P2P
- p2p_ps_wk_cmd23a(Adapter, P2P_PS_DISABLE, enqueue);
-#endif /* CONFIG_8723AU_P2P */
-
rtw_lps_ctrl_wk_cmd23a(Adapter, LPS_CTRL_LEAVE, enqueue);
}
{
}
-u8 rtw_interface_ps_func23a(struct rtw_adapter *padapter, enum hal_intf_ps_func efunc_id, u8* val)
-{
- u8 bResult = true;
- rtw_hal_intf_ps_func23a(padapter, efunc_id, val);
-
- return bResult;
-}
-
inline void rtw_set_ips_deny23a(struct rtw_adapter *padapter, u32 ms)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
#include <mlme_osdep.h>
#include <linux/ip.h>
#include <linux/if_ether.h>
-#include <ethernet.h>
#include <usb_ops.h>
#include <linux/ieee80211.h>
#include <wifi.h>
list_add_tail(&precvframe->list,
&precvpriv->free_recv_queue.queue);
- res = rtw_os_recv_resource_alloc23a(padapter, precvframe);
-
precvframe->adapter = padapter;
precvframe++;
}
static struct recv_frame *portctrl(struct rtw_adapter *adapter,
struct recv_frame *precv_frame)
{
- u8 *psta_addr = NULL, *ptr;
+ 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 = 0;
- u16 eapol_type = 0x888e;/* for Funia BD's WPA issue */
+ u16 ether_type;
+ u16 eapol_type = ETH_P_PAE;/* for Funia BD's WPA issue */
struct rx_pkt_attrib *pattrib;
pstapriv = &adapter->stapriv;
- psta = rtw_get_stainfo23a(pstapriv, psta_addr);
auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
- ptr = precv_frame->pkt->data;
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));
- if (auth_alg == 2) {
+ if (auth_alg == dot11AuthAlgrthm_8021X) {
+ /* get ether_type */
+ ptr = pfhdr->pkt->data + pfhdr->attrib.hdrlen;
+
+ ether_type = (ptr[6] << 8) | ptr[7];
+
if ((psta != NULL) && (psta->ieee8021x_blocked)) {
/* blocked */
/* only accept EAPOL frame */
("########portctrl:psta->ieee8021x_blocked =="
"1\n"));
- prtnframe = precv_frame;
-
- /* get ether_type */
- ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE;
- memcpy(ðer_type, ptr, 2);
- ether_type = ntohs((unsigned short)ether_type);
-
if (ether_type == eapol_type) {
prtnframe = precv_frame;
} else {
prtnframe = precv_frame;
}
-
-
- return prtnframe;
+ return prtnframe;
}
int recv_decache(struct recv_frame *precv_frame, u8 bretry,
/* upate BCN for TIM IE */
/* update_BCNTIM(padapter); */
- update_beacon23a(padapter, _TIM_IE_,
- NULL, false);
+ update_beacon23a(padapter, WLAN_EID_TIM,
+ NULL, false);
}
/* spin_unlock_bh(&psta->sleep_q.lock); */
/* upate BCN for TIM IE */
/* update_BCNTIM(padapter); */
- update_beacon23a(padapter, _TIM_IE_,
- NULL, false);
+ update_beacon23a(padapter, WLAN_EID_TIM,
+ NULL, false);
}
}
}
return true;
}
-int enqueue_reorder_recvframe23a(struct recv_reorder_ctrl *preorder_ctrl,
- struct recv_frame *prframe)
+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;
/* s1. */
wlanhdr_to_ethhdr(prframe);
- if ((pattrib->qos!= 1) || (pattrib->eth_type == 0x0806) ||
+ if ((pattrib->qos!= 1) || (pattrib->eth_type == ETH_P_ARP) ||
(pattrib->ack_policy != 0)) {
if ((padapter->bDriverStopped == false) &&
(padapter->bSurpriseRemoved == false)) {
val8 = 0xcc;
else
val8 = 0xcf;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
+
+ rtl8723a_set_sec_cfg(padapter, val8);
if ((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
threshold = 1;
else
threshold = 0;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
- } else {
+ } else
threshold = 1;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
- }
- set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
+ rtl8723a_set_rxdma_agg_pg_th(padapter, threshold);
- /* disable dynamic functions, such as high power, DIG */
- /* Switch_DM_Func23a(padapter, DYNAMIC_FUNC_DISABLE, false); */
+ set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
+ pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
-
- {
- u8 join_type = 0;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
- }
+ hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
+ hw_var_set_mlme_join(padapter, 0);
Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
#include <mlme_osdep.h>
#include <sta_info.h>
-void _rtw_init_stainfo(struct sta_info *psta)
+static void _rtw_init_stainfo(struct sta_info *psta)
{
memset((u8 *)psta, 0, sizeof (struct sta_info));
spin_lock_init(&psta->lock);
}
/* this function is used to free the memory of lock || sema for all stainfos */
-void rtw_mfree_all_stainfo(struct sta_priv *pstapriv)
+static void rtw_mfree_all_stainfo(struct sta_priv *pstapriv)
{
struct list_head *plist, *phead;
struct sta_info *psta;
spin_unlock_bh(&pstapriv->sta_hash_lock);
}
-void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv)
+static void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv)
{
rtw_mfree_all_stainfo(pstapriv); /* be done before free sta_hash_lock */
}
}
/* any station allocated can be searched by hash list */
-struct sta_info *rtw_get_stainfo23a(struct sta_priv *pstapriv, u8 *hwaddr)
+struct sta_info *rtw_get_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr)
{
struct list_head *plist, *phead;
struct sta_info *psta = NULL;
u32 index;
- u8 *addr;
+ const u8 *addr;
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
if (hwaddr == NULL)
return network_type;
}
-unsigned char ratetbl_val_2wifirate(unsigned char rate)
+static unsigned char ratetbl_val_2wifirate(unsigned char rate)
{
unsigned char val = 0;
return val;
}
-int is_basicrate(struct rtw_adapter *padapter, unsigned char rate)
+static int is_basicrate(struct rtw_adapter *padapter, unsigned char rate)
{
int i;
unsigned char val;
return false;
}
-unsigned int ratetbl2rateset(struct rtw_adapter *padapter, unsigned char *rateset)
+static unsigned int ratetbl2rateset(struct rtw_adapter *padapter,
+ unsigned char *rateset)
{
int i;
unsigned char rate;
}
}
-void Save_DM_Func_Flag23a(struct rtw_adapter *padapter)
-{
- u8 bSaveFlag = true;
-
- rtw_hal_set_hwreg23a(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&bSaveFlag));
-}
-
-void Restore_DM_Func_Flag23a(struct rtw_adapter *padapter)
-{
- u8 bSaveFlag = false;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&bSaveFlag));
-}
-
-void Switch_DM_Func23a(struct rtw_adapter *padapter, unsigned long mode, u8 enable)
-{
- if (enable == true)
- rtw_hal_set_hwreg23a(padapter, HW_VAR_DM_FUNC_SET, (u8 *)(&mode));
- else
- rtw_hal_set_hwreg23a(padapter, HW_VAR_DM_FUNC_CLR, (u8 *)(&mode));
-}
-
-static void Set_NETYPE0_MSR(struct rtw_adapter *padapter, u8 type)
-{
- rtw_hal_set_hwreg23a(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type));
-}
-
void Set_MSR23a(struct rtw_adapter *padapter, u8 type)
{
- Set_NETYPE0_MSR(padapter, type);
+ rtl8723a_set_media_status(padapter, type);
}
inline u8 rtw_get_oper_ch23a(struct rtw_adapter *adapter)
return bcn_interval << 2;
}
-void CAM_empty_entry23a(struct rtw_adapter *Adapter, u8 ucIndex)
-{
- rtw_hal_set_hwreg23a(Adapter, HW_VAR_CAM_EMPTY_ENTRY, (u8 *)(&ucIndex));
-}
-
void invalidate_cam_all23a(struct rtw_adapter *padapter)
{
- rtw_hal_set_hwreg23a(padapter, HW_VAR_CAM_INVALID_ALL, NULL);
-}
-
-void write_cam23a(struct rtw_adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key)
-{
- unsigned int i, val, addr;
- int j;
- u32 cam_val[2];
-
- 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;
- }
-
- cam_val[0] = val;
- cam_val[1] = addr + (unsigned int)j;
-
- rtw_hal_set_hwreg23a(padapter, HW_VAR_CAM_WRITE, (u8 *)cam_val);
-
- /* rtw_write32(padapter, WCAMI, val); */
-
- /* cmd = CAM_POLLINIG | CAM_WRITE | (addr + j); */
- /* rtw_write32(padapter, RWCAM, cmd); */
-
- /* DBG_8723A("%s => cam write: %x, %x\n", __func__, cmd, val); */
-
- }
+ rtl8723a_cam_invalid_all(padapter);
}
void clear_cam_entry23a(struct rtw_adapter *padapter, u8 entry)
unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- write_cam23a(padapter, entry, 0, null_sta, null_key);
+ rtl8723a_cam_write(padapter, entry, 0, null_sta, null_key);
}
int allocate_fw_sta_entry23a(struct rtw_adapter *padapter)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_CAM_INVALID_ALL, NULL);
+ rtl8723a_cam_invalid_all(padapter);
memset((u8 *)(pmlmeinfo->FW_sta_info), 0, sizeof(pmlmeinfo->FW_sta_info));
}
-#if defined(CONFIG_8723AU_P2P) && defined(CONFIG_8723AU_P2P)
-int WFD_info_handler(struct rtw_adapter *padapter, struct ndis_802_11_var_ies * pIE)
-{
- struct wifidirect_info *pwdinfo;
- u8 wfd_ie[128] = {0x00};
- u32 wfd_ielen = 0;
-
- pwdinfo = &padapter->wdinfo;
- if (rtw_get_wfd_ie((u8 *) pIE, pIE->Length, wfd_ie, &wfd_ielen)) {
- u8 attr_content[ 10 ] = { 0x00 };
- u32 attr_contentlen = 0;
-
- DBG_8723A("[%s] Found WFD IE\n", __func__);
- rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
- if (attr_contentlen) {
- pwdinfo->wfd_info->peer_rtsp_ctrlport = get_unaligned_be16(attr_content + 2);
- DBG_8723A("[%s] Peer PORT NUM = %d\n", __func__, pwdinfo->wfd_info->peer_rtsp_ctrlport);
- return true;
- }
- } else {
- DBG_8723A("[%s] NO WFD IE\n", __func__);
- }
- return _FAIL;
-}
-#endif
-
int WMM_param_handler23a(struct rtw_adapter *padapter, struct ndis_802_11_var_ies * pIE)
{
/* struct registry_priv *pregpriv = &padapter->registrypriv; */
switch (ACI) {
case 0x0:
- rtw_hal_set_hwreg23a(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
+ rtl8723a_set_ac_param_be(padapter, acParm);
acm_mask |= (ACM? BIT(1):0);
edca[XMIT_BE_QUEUE] = acParm;
break;
case 0x1:
- rtw_hal_set_hwreg23a(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
+ rtl8723a_set_ac_param_bk(padapter, acParm);
/* acm_mask |= (ACM? BIT(0):0); */
edca[XMIT_BK_QUEUE] = acParm;
break;
case 0x2:
- rtw_hal_set_hwreg23a(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
+ rtl8723a_set_ac_param_vi(padapter, acParm);
acm_mask |= (ACM? BIT(2):0);
edca[XMIT_VI_QUEUE] = acParm;
break;
case 0x3:
- rtw_hal_set_hwreg23a(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
+ rtl8723a_set_ac_param_vo(padapter, acParm);
acm_mask |= (ACM? BIT(3):0);
edca[XMIT_VO_QUEUE] = acParm;
break;
}
if (padapter->registrypriv.acm_method == 1)
- rtw_hal_set_hwreg23a(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask));
+ 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, tmp, change_inx;
+ u32 j, tmp, change_inx = false;
/* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */
for (i = 0; i < 4; i++) {
pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps = le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps);
- rtw23a_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+ rf_type = rtl8723a_get_rf_type(padapter);
/* update the MCS rates */
for (i = 0; i < 16; i++) {
min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
-
- rtw_hal_set_hwreg23a(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
+ 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, struct ndis_802_11_var_ies * pIE)
}
}
-int rtw_check_bcn_info23a(struct rtw_adapter *Adapter, u8 *pframe, u32 packet_len)
+int rtw_check_bcn_info23a(struct rtw_adapter *Adapter,
+ struct ieee80211_mgmt *mgmt, u32 pkt_len)
{
- unsigned int len;
- unsigned char *p;
- unsigned short val16;
struct wlan_network *cur_network = &Adapter->mlmepriv.cur_network;
- u16 wpa_len = 0, rsn_len = 0;
- u8 encryp_protocol = 0;
+ struct HT_info_element *pht_info;
+ struct ieee80211_ht_cap *pht_cap;
struct wlan_bssid_ex *bssid;
- int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0;
- unsigned char *pbuf;
- u32 wpa_ielen = 0;
- u32 hidden_ssid = 0;
- struct HT_info_element *pht_info = NULL;
- struct ieee80211_ht_cap *pht_cap = NULL;
+ unsigned short val16;
+ u16 wpa_len = 0, rsn_len = 0;
+ u8 encryp_protocol;
+ int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0, r;
u32 bcn_channel;
- unsigned short ht_cap_info;
- unsigned char ht_info_infos_0;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) pframe;
- u8 *pbssid = hdr->addr3;
+ unsigned short ht_cap_info;
+ unsigned char ht_info_infos_0;
+ int len, pie_len, ie_offset;
+ const u8 *p;
+ u8 *pie;
if (is_client_associated_to_ap23a(Adapter) == false)
return true;
- len = packet_len - sizeof(struct ieee80211_hdr_3addr);
+ if (unlikely(!ieee80211_is_beacon(mgmt->frame_control))) {
+ printk(KERN_WARNING "%s: received a non beacon frame!\n",
+ __func__);
+ return false;
+ }
+
+ len = pkt_len - sizeof(struct ieee80211_hdr_3addr);
if (len > MAX_IE_SZ) {
DBG_8723A("%s IE too long for survey event\n", __func__);
return _FAIL;
}
- if (memcmp(cur_network->network.MacAddress, pbssid, 6)) {
- DBG_8723A("Oops: rtw_check_network_encrypt linked but recv other bssid bcn\n" MAC_FMT MAC_FMT,
- MAC_ARG(pbssid), MAC_ARG(cur_network->network.MacAddress));
+ if (memcmp(cur_network->network.MacAddress, mgmt->bssid, 6)) {
+ DBG_8723A("Oops: rtw_check_network_encrypt linked but recv "
+ "other bssid bcn\n" MAC_FMT MAC_FMT,
+ MAC_ARG(mgmt->bssid),
+ MAC_ARG(cur_network->network.MacAddress));
return true;
}
bssid = (struct wlan_bssid_ex *)kzalloc(sizeof(struct wlan_bssid_ex),
- GFP_ATOMIC);
+ GFP_ATOMIC);
+ if (!bssid)
+ return _FAIL;
- if (ieee80211_is_beacon(hdr->frame_control))
- bssid->reserved = 1;
+ bssid->reserved = 1;
- bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
+ bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + len;
/* below is to copy the information element */
bssid->IELength = len;
- memcpy(bssid->IEs, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->IELength);
+ memcpy(bssid->IEs, &mgmt->u, len);
/* check bw and channel offset */
/* parsing HT_CAP_IE */
- p = rtw_get_ie23a(bssid->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
- if (p && len>0) {
- pht_cap = (struct ieee80211_ht_cap *)(p + 2);
- ht_cap_info = pht_cap->cap_info;
+ ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
+ offsetof(struct ieee80211_mgmt, u);
+ pie = bssid->IEs + ie_offset;
+ pie_len = pkt_len - ie_offset;
+
+ p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, pie_len);
+ if (p && p[1] > 0) {
+ pht_cap = (struct ieee80211_ht_cap *)(p + 2);
+ ht_cap_info = pht_cap->cap_info;
} else {
- ht_cap_info = 0;
+ pht_cap = NULL;
+ ht_cap_info = 0;
}
+
/* parsing HT_INFO_IE */
- p = rtw_get_ie23a(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
- if (p && len>0) {
- pht_info = (struct HT_info_element *)(p + 2);
- ht_info_infos_0 = pht_info->infos[0];
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pie, pie_len);
+ if (p && p[1] > 0) {
+ pht_info = (struct HT_info_element *)(p + 2);
+ ht_info_infos_0 = pht_info->infos[0];
} else {
- ht_info_infos_0 = 0;
+ pht_info = NULL;
+ ht_info_infos_0 = 0;
}
+
if (ht_cap_info != cur_network->BcnInfo.ht_cap_info ||
- ((ht_info_infos_0&0x03) != (cur_network->BcnInfo.ht_info_infos_0&0x03))) {
- DBG_8723A("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
- ht_cap_info, ht_info_infos_0);
- DBG_8723A("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
- cur_network->BcnInfo.ht_cap_info, cur_network->BcnInfo.ht_info_infos_0);
- DBG_8723A("%s bw mode change, disconnect\n", __func__);
- /* bcn_info_update */
- cur_network->BcnInfo.ht_cap_info = ht_cap_info;
- cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0;
- /* to do : need to check that whether modify related register of BB or not */
+ ((ht_info_infos_0 & 0x03) !=
+ (cur_network->BcnInfo.ht_info_infos_0 & 0x03))) {
+ DBG_8723A("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n",
+ __func__, ht_cap_info, ht_info_infos_0);
+ DBG_8723A("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n",
+ __func__, cur_network->BcnInfo.ht_cap_info,
+ cur_network->BcnInfo.ht_info_infos_0);
+ DBG_8723A("%s bw mode change, disconnect\n", __func__);
+ /* bcn_info_update */
+ cur_network->BcnInfo.ht_cap_info = ht_cap_info;
+ cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0;
+ /* to do : need to check that whether modify related
+ register of BB or not */
}
/* Checking for channel */
- p = rtw_get_ie23a(bssid->IEs + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
- if (p) {
- bcn_channel = *(p + 2);
- } else {/* In 5G, some ap do not have DSSET IE checking HT info for channel */
- p = rtw_get_ie23a(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
- if (pht_info) {
- bcn_channel = pht_info->primary_channel;
- } 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;
- }
+ p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, pie, 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, pie, pie_len);
+
+ if (pht_info)
+ bcn_channel = pht_info->primary_channel;
+ 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;
+ DBG_8723A("%s beacon channel:%d cur channel:%d disconnect\n",
+ __func__, bcn_channel,
+ Adapter->mlmeextpriv.cur_channel);
+ goto _mismatch;
}
/* checking SSID */
- if ((p = rtw_get_ie23a(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_)) == NULL) {
- DBG_8723A("%s marc: cannot find SSID for survey event\n", __func__);
- hidden_ssid = true;
- } else {
- hidden_ssid = false;
- }
-
- if ((NULL != p) && (false == hidden_ssid && (*(p + 1)))) {
- memcpy(bssid->Ssid.ssid, (p + 2), *(p + 1));
- bssid->Ssid.ssid_len = *(p + 1);
+ p = cfg80211_find_ie(WLAN_EID_SSID, pie, pie_len);
+ if (p && p[1]) {
+ memcpy(bssid->Ssid.ssid, p + 2, p[1]);
+ bssid->Ssid.ssid_len = p[1];
} else {
+ DBG_8723A("%s marc: cannot find SSID for survey event\n",
+ __func__);
bssid->Ssid.ssid_len = 0;
bssid->Ssid.ssid[0] = '\0';
}
}
/* check encryption info */
- val16 = rtw_get_capability23a((struct wlan_bssid_ex *)bssid);
+ val16 = rtw_get_capability23a(bssid);
if (val16 & BIT(4))
bssid->Privacy = 1;
bssid->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, bssid->Privacy));
+ ("%s(): cur_network->network.Privacy is %d, bssid.Privacy "
+ "is %d\n", __func__, cur_network->network.Privacy,
+ bssid->Privacy));
if (cur_network->network.Privacy != bssid->Privacy) {
DBG_8723A("%s(), privacy is not match return FAIL\n", __func__);
goto _mismatch;
}
- rtw_get_sec_ie23a(bssid->IEs, bssid->IELength, NULL,&rsn_len, NULL,&wpa_len);
+ rtw_get_sec_ie23a(bssid->IEs, bssid->IELength, NULL, &rsn_len, NULL,
+ &wpa_len);
- if (rsn_len > 0) {
+ if (rsn_len > 0)
encryp_protocol = ENCRYP_PROTOCOL_WPA2;
- } else if (wpa_len > 0) {
+ else if (wpa_len > 0)
encryp_protocol = ENCRYP_PROTOCOL_WPA;
- } else {
+ else {
if (bssid->Privacy)
encryp_protocol = ENCRYP_PROTOCOL_WEP;
+ else
+ encryp_protocol = ENCRYP_PROTOCOL_OPENSYS;
}
if (cur_network->BcnInfo.encryp_protocol != encryp_protocol) {
- DBG_8723A("%s(): enctyp is not match , return FAIL\n", __func__);
+ DBG_8723A("%s(): enctyp is not match, return FAIL\n", __func__);
goto _mismatch;
}
- if (encryp_protocol == ENCRYP_PROTOCOL_WPA || encryp_protocol == ENCRYP_PROTOCOL_WPA2) {
- pbuf = rtw_get_wpa_ie23a(&bssid->IEs[12], &wpa_ielen, bssid->IELength-12);
- if (pbuf && (wpa_ielen>0)) {
- if (_SUCCESS == rtw_parse_wpa_ie23a(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is_8021x)) {
+ if (encryp_protocol == ENCRYP_PROTOCOL_WPA ||
+ encryp_protocol == ENCRYP_PROTOCOL_WPA2) {
+ p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPA,
+ pie, pie_len);
+ if (p && p[1] > 0) {
+ 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));
- }
+ ("%s pnetwork->pairwise_cipher: %d, "
+ "group_cipher is %d, is_8021x is "
+ "%d\n", __func__, pairwise_cipher,
+ group_cipher, is_8021x));
} else {
- pbuf = rtw_get_wpa2_ie23a(&bssid->IEs[12], &wpa_ielen, bssid->IELength-12);
-
- if (pbuf && (wpa_ielen>0)) {
- if (_SUCCESS == rtw_parse_wpa2_ie23a(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is_8021x)) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- ("%s pnetwork->pairwise_cipher: %d, pnetwork->group_cipher is %d, is_802x is %d\n",
- __func__, pairwise_cipher, group_cipher, is_8021x));
- }
+ p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
+
+ if (p && p[1] > 0) {
+ 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"
+ " is %d, is_802x is %d\n",
+ __func__, pairwise_cipher,
+ group_cipher, is_8021x));
}
}
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);
+ ("%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__);
+ DBG_8723A("%s authentication is not match, return "
+ "FAIL\n", __func__);
goto _mismatch;
}
}
pIE = (struct ndis_802_11_var_ies *)(pframe + (_BEACON_IE_OFFSET_ + sizeof(struct ieee80211_hdr_3addr)) + i);
switch (pIE->ElementID) {
- case _HT_EXTRA_INFO_IE_: /* HT info */
+ case WLAN_EID_HT_OPERATION: /* HT info */
/* HT_info_handler23a(padapter, pIE); */
bwmode_update_check(padapter, pIE);
break;
- case _ERPINFO_IE_:
+ case WLAN_EID_ERP_INFO:
ERP_IE_handler23a(padapter, pIE);
VCS_update23a(padapter, psta);
break;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
- if (rtw_get_capability23a((struct wlan_bssid_ex *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
+ if (rtw_get_capability23a(cur_network) & WLAN_CAPABILITY_PRIVACY) {
for (i = sizeof(struct ndis_802_11_fixed_ies); i < pmlmeinfo->network.IELength;) {
pIE = (struct ndis_802_11_var_ies *)(pmlmeinfo->network.IEs + i);
switch (pIE->ElementID) {
- case _VENDOR_SPECIFIC_IE_:
- if ((!memcmp(pIE->data, RTW_WPA_OUI23A, 4)) && (!memcmp((pIE->data + 12), WPA_TKIP_CIPHER23A, 4)))
+ case WLAN_EID_VENDOR_SPECIFIC:
+ if ((!memcmp(pIE->data, RTW_WPA_OUI23A_TYPE, 4)) && (!memcmp((pIE->data + 12), WPA_TKIP_CIPHER23A, 4)))
return true;
break;
- case _RSN_IE_2_:
+ case WLAN_EID_RSN:
if (!memcmp((pIE->data + 8), RSN_TKIP_CIPHER23A, 4))
return true;
break;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_bssid_ex *cur_network = &pmlmepriv->cur_network.network;
- if (rtw_get_capability23a((struct wlan_bssid_ex *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
+ if (rtw_get_capability23a(cur_network) & WLAN_CAPABILITY_PRIVACY) {
for (i = sizeof(struct ndis_802_11_fixed_ies); i < cur_network->IELength;) {
pIE = (struct ndis_802_11_var_ies *)(cur_network->IEs + i);
switch (pIE->ElementID) {
- case _VENDOR_SPECIFIC_IE_:
- if (!memcmp(pIE->data, RTW_WPA_OUI23A, 4) &&
+ case WLAN_EID_VENDOR_SPECIFIC:
+ if (!memcmp(pIE->data, RTW_WPA_OUI23A_TYPE, 4) &&
((!memcmp((pIE->data + 12), WPA_CIPHER_SUITE_CCMP23A, 4)) ||
(!memcmp((pIE->data + 16), WPA_CIPHER_SUITE_CCMP23A, 4))))
return false;
break;
- case _RSN_IE_2_:
+ case WLAN_EID_RSN:
if ((!memcmp((pIE->data + 8), RSN_CIPHER_SUITE_CCMP23A, 4)) ||
(!memcmp((pIE->data + 12), RSN_CIPHER_SUITE_CCMP23A, 4)))
return false;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
- if (rtw_get_capability23a((struct wlan_bssid_ex *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
+ if (rtw_get_capability23a(cur_network) & WLAN_CAPABILITY_PRIVACY) {
for (i = sizeof(struct ndis_802_11_fixed_ies); i < pmlmeinfo->network.IELength;) {
pIE = (struct ndis_802_11_var_ies *)(pmlmeinfo->network.IEs + i);
switch (pIE->ElementID) {
- case _VENDOR_SPECIFIC_IE_:
- if (!memcmp(pIE->data, RTW_WPA_OUI23A, 4))
+ case WLAN_EID_VENDOR_SPECIFIC:
+ if (!memcmp(pIE->data, RTW_WPA_OUI23A_TYPE, 4))
return false;
break;
- case _RSN_IE_2_:
+ case WLAN_EID_RSN:
return false;
default:
}
}
-int wifirate2_ratetbl_inx23a(unsigned char rate)
+static int wifirate2_ratetbl_inx23a(unsigned char rate)
{
int inx = 0;
rate = rate & 0x7f;
return rate_idx;
}
-unsigned char get_highest_mcs_rate(struct HT_caps_element *pHT_caps)
-{
- int i, mcs_rate;
-
- mcs_rate = (pHT_caps->u.HT_cap_element.MCS_rate[0] | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 8));
-
- for (i = 15; i >= 0; i--) {
- if (mcs_rate & (0x1 << i))
- break;
- }
- return i;
-}
-
void Update_RA_Entry23a(struct rtw_adapter *padapter, struct sta_info *psta)
{
rtw_hal_update_ra_mask23a(psta, 0);
}
-void enable_rate_adaptive(struct rtw_adapter *padapter, struct sta_info *psta)
+static void enable_rate_adaptive(struct rtw_adapter *padapter,
+ struct sta_info *psta)
{
Update_RA_Entry23a(padapter, psta);
}
void update_tx_basic_rate23a(struct rtw_adapter *padapter, u8 wirelessmode)
{
unsigned char supported_rates[NDIS_802_11_LENGTH_RATES_EX];
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info* pwdinfo = &padapter->wdinfo;
-
- /* Added by Albert 2011/03/22 */
- /* In the P2P mode, the driver should not support the b mode. */
- /* So, the Tx packet shouldn't use the CCK rate */
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
-#endif /* CONFIG_8723AU_P2P */
memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
else
update_mgnt_tx_rate23a(padapter, IEEE80211_OFDM_RATE_6MB);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BASIC_RATE, supported_rates);
+ HalSetBrateCfg23a(padapter, supported_rates);
}
unsigned char check_assoc_AP23a(u8 *pframe, uint len)
pIE = (struct ndis_802_11_var_ies *)(pframe + i);
switch (pIE->ElementID) {
- case _VENDOR_SPECIFIC_IE_:
+ case WLAN_EID_VENDOR_SPECIFIC:
if ((!memcmp(pIE->data, ARTHEROS_OUI1, 3)) ||
(!memcmp(pIE->data, ARTHEROS_OUI2, 3))) {
DBG_8723A("link to Artheros AP\n");
pmlmeinfo->turboMode_cts2self = 0;
pmlmeinfo->turboMode_rtsen = 1;
/* disable high power */
- Switch_DM_Func23a(padapter, ~DYNAMIC_BB_DYNAMIC_TXPWR,
- false);
+ 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 */
- Switch_DM_Func23a(padapter, ~DYNAMIC_BB_DYNAMIC_TXPWR,
- false);
+ rtl8723a_odm_support_ability_clr(padapter, (u32)
+ ~DYNAMIC_BB_DYNAMIC_TXPWR);
break;
default:
pmlmeinfo->turboMode_cts2self = 0;
{
struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- bool ShortPreamble;
if (updateCap & cShortPreamble) {
/* Short Preamble */
if (pmlmeinfo->preamble_mode != PREAMBLE_SHORT) {
/* PREAMBLE_LONG or PREAMBLE_AUTO */
- ShortPreamble = true;
pmlmeinfo->preamble_mode = PREAMBLE_SHORT;
- rtw_hal_set_hwreg23a(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble);
+ rtl8723a_ack_preamble(Adapter, true);
}
} else { /* Long Preamble */
if (pmlmeinfo->preamble_mode != PREAMBLE_LONG) {
/* PREAMBLE_SHORT or PREAMBLE_AUTO */
- ShortPreamble = false;
pmlmeinfo->preamble_mode = PREAMBLE_LONG;
- rtw_hal_set_hwreg23a(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble);
+ rtl8723a_ack_preamble(Adapter, false);
}
}
if (updateCap & cIBSS) {
pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
}
}
- rtw_hal_set_hwreg23a(Adapter, HW_VAR_SLOT_TIME, &pmlmeinfo->slotTime);
+ rtl8723a_set_slot_time(Adapter, pmlmeinfo->slotTime);
}
void update_wireless_mode23a(struct rtw_adapter *padapter)
{
int ratelen, network_type = 0;
- u32 SIFS_Timer;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode;
- 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);
+ /* 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);
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);
+ 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, 4);
+ 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 update_sta_support_rate23a(struct rtw_adapter *padapter, u8 *pvar_ie,
+ uint var_ie_len, int cam_idx)
{
- unsigned int ie_len;
- struct ndis_802_11_var_ies *pIE;
- int supportRateNum = 0;
+ int supportRateNum = 0;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ const u8 *p;
- pIE = (struct ndis_802_11_var_ies *)rtw_get_ie23a(pvar_ie, _SUPPORTEDRATES_IE_, &ie_len, var_ie_len);
- if (pIE == NULL)
+ 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, pIE->data, ie_len);
- supportRateNum = ie_len;
+ memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates, p + 2, p[1]);
+ supportRateNum = p[1];
- pIE = (struct ndis_802_11_var_ies *)rtw_get_ie23a(pvar_ie, _EXT_SUPPORTEDRATES_IE_, &ie_len, var_ie_len);
- if (pIE)
- memcpy((pmlmeinfo->FW_sta_info[cam_idx].SupportedRates + supportRateNum), pIE->data, ie_len);
+ 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 update_TSF23a(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len)
-{
- u8 *pIE;
- u32 *pbuf;
-
- pIE = pframe + sizeof(struct ieee80211_hdr_3addr);
- pbuf = (u32 *)pIE;
-
- pmlmeext->TSFValue = le32_to_cpu(*(pbuf+1));
-
- pmlmeext->TSFValue = pmlmeext->TSFValue << 32;
-
- pmlmeext->TSFValue |= le32_to_cpu(*pbuf);
-}
-
-void correct_TSF23a(struct rtw_adapter *padapter, struct mlme_ext_priv *pmlmeext)
-{
- rtw_hal_set_hwreg23a(padapter, HW_VAR_CORRECT_TSF, NULL);
-}
-
void beacon_timing_control23a(struct rtw_adapter *padapter)
{
rtw_hal_bcn_related_reg_setting23a(padapter);
return change_priority;
}
-static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
+static void set_qos(struct sk_buff *skb, struct pkt_attrib *pattrib)
{
- struct ethhdr etherhdr;
- struct iphdr ip_hdr;
+ u8 *pframe = skb->data;
+ struct iphdr *ip_hdr;
s32 UserPriority = 0;
- _rtw_open_pktfile23a(ppktfile->pkt, ppktfile);
- _rtw_pktfile_read23a(ppktfile, (unsigned char*)ðerhdr, ETH_HLEN);
-
/* get UserPriority from IP hdr */
- if (pattrib->ether_type == 0x0800) {
- _rtw_pktfile_read23a(ppktfile, (u8*)&ip_hdr, sizeof(ip_hdr));
-/* UserPriority = (ntohs(ip_hdr.tos) >> 5) & 0x3; */
- UserPriority = ip_hdr.tos >> 5;
- } else if (pattrib->ether_type == 0x888e) {
+ 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." */
}
static s32 update_attrib(struct rtw_adapter *padapter,
- struct sk_buff *pkt, struct pkt_attrib *pattrib)
+ struct sk_buff *skb, struct pkt_attrib *pattrib)
{
- uint i;
- struct pkt_file pktfile;
struct sta_info *psta = NULL;
- struct ethhdr etherhdr;
-
int bmcast;
struct sta_priv *pstapriv = &padapter->stapriv;
struct security_priv *psecuritypriv = &padapter->securitypriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct qos_priv *pqospriv = &pmlmepriv->qospriv;
int res = _SUCCESS;
+ struct ethhdr *ehdr = (struct ethhdr *) skb->data;
- _rtw_open_pktfile23a(pkt, &pktfile);
- i = _rtw_pktfile_read23a(&pktfile, (u8*)ðerhdr, ETH_HLEN);
-
- pattrib->ether_type = ntohs(etherhdr.h_proto);
+ pattrib->ether_type = ntohs(ehdr->h_proto);
- memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN);
- memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN);
+ 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) == true) ||
(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
- memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
- memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+ ether_addr_copy(pattrib->ra, pattrib->dst);
+ ether_addr_copy(pattrib->ta, pattrib->src);
}
else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
- memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
- memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+ ether_addr_copy(pattrib->ra, get_bssid(pmlmepriv));
+ ether_addr_copy(pattrib->ta, pattrib->src);
}
else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
- memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
+ ether_addr_copy(pattrib->ra, pattrib->dst);
+ ether_addr_copy(pattrib->ta, get_bssid(pmlmepriv));
}
- pattrib->pktlen = pktfile.pkt_len;
+ 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 */
- u8 tmp[24];
- _rtw_pktfile_read23a(&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 (((tmp[21] == 68) && (tmp[23] == 67)) ||
- ((tmp[21] == 67) && (tmp[23] == 68))) {
+ /* 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_,
}
}
}
- } else if (0x888e == pattrib->ether_type) {
+ } else if (pattrib->ether_type == ETH_P_PAE) {
DBG_8723A_LEVEL(_drv_always_, "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_cmd23a(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
}
if (check_fwstate(pmlmepriv, WIFI_AP_STATE | WIFI_ADHOC_STATE |
WIFI_ADHOC_MASTER_STATE)) {
if (psta->qos_option)
- set_qos(&pktfile, pattrib);
+ set_qos(skb, pattrib);
} else {
if (pqospriv->qos_option) {
- set_qos(&pktfile, pattrib);
+ set_qos(skb, pattrib);
if (pmlmepriv->acm_mask != 0) {
pattrib->priority = qos_acm23a(pmlmepriv->acm_mask,
pattrib->encrypt = 0;
- if ((pattrib->ether_type != 0x888e) &&
+ if ((pattrib->ether_type != ETH_P_PAE) &&
(check_fwstate(pmlmepriv, WIFI_MP_STATE) == false)) {
RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
("\npsta->ieee8021x_blocked == true, "
struct qos_priv *pqospriv = &pmlmepriv->qospriv;
u8 qos_option = false;
int res = _SUCCESS;
- u16 *fctrl = &pwlanhdr->frame_control;
+ __le16 *fctrl = &pwlanhdr->frame_control;
struct sta_info *psta;
6. apply sw-encrypt, if necessary.
*/
-s32 rtw_xmitframe_coalesce23a(struct rtw_adapter *padapter, struct sk_buff *pkt,
+s32 rtw_xmitframe_coalesce23a(struct rtw_adapter *padapter, struct sk_buff *skb,
struct xmit_frame *pxmitframe)
{
- struct pkt_file pktfile;
- struct sta_info *psta;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct sta_info *psta;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
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);
s32 res = _SUCCESS;
- if (pattrib->psta) {
+ if (pattrib->psta)
psta = pattrib->psta;
- } else {
+ else {
DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra);
}
- if (psta == NULL) {
+ 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);
+ DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
+ __func__, psta->state);
return _FAIL;
}
- if (pxmitframe->buf_addr == NULL) {
+ if (!pxmitframe->buf_addr) {
DBG_8723A("==> %s buf_addr == NULL\n", __func__);
return _FAIL;
}
hw_hdr_offset = TXDESC_OFFSET;
- mem_start = pbuf_start + hw_hdr_offset;
+ mem_start = pbuf_start + hw_hdr_offset;
if (rtw_make_wlanhdr23a(padapter, mem_start, pattrib) == _FAIL) {
RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
goto exit;
}
- _rtw_open_pktfile23a(pkt, &pktfile);
- _rtw_pktfile_read23a(&pktfile, NULL, pattrib->pkt_hdrlen);
+ pdata += pattrib->pkt_hdrlen;
+ data_len -= pattrib->pkt_hdrlen;
frg_inx = 0;
frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
/* adding icv, if necessary... */
if (pattrib->iv_len) {
- if (psta != NULL) {
+ if (psta) {
switch (pattrib->encrypt) {
case _WEP40_:
case _WEP104_:
- WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
+ WEP_IV(pattrib->iv, psta->dot11txpn,
+ pattrib->key_idx);
break;
case _TKIP_:
if (bmcst)
- TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
+ TKIP_IV(pattrib->iv,
+ psta->dot11txpn,
+ pattrib->key_idx);
else
- TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
+ TKIP_IV(pattrib->iv,
+ psta->dot11txpn, 0);
break;
case _AES_:
if (bmcst)
- AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
+ AES_IV(pattrib->iv,
+ psta->dot11txpn,
+ pattrib->key_idx);
else
- AES_IV(pattrib->iv, psta->dot11txpn, 0);
+ AES_IV(pattrib->iv,
+ psta->dot11txpn, 0);
break;
}
}
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) {
+ if (bmcst)
/* don't do fragment to broadcat/multicast packets */
- mem_sz = _rtw_pktfile_read23a(&pktfile, pframe, pattrib->pktlen);
- } else {
- mem_sz = _rtw_pktfile_read23a(&pktfile, pframe, mpdu_len);
- }
+ 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);
frg_inx++;
- if (bmcst || (rtw_endofpktfile23a(&pktfile))) {
+ if (bmcst || data_len <= 0) {
pattrib->nr_frags = frg_inx;
pattrib->last_txcmdsz = pattrib->hdrlen +
break;
} else {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: There're still something in packet!\n", __func__));
+ RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
+ ("%s: There're still something in packet!\n",
+ __func__));
}
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"));
+ 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;
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;
- u8 *perp;
- int erp_len;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ uint protection;
+ const u8 *p;
switch (pxmitpriv->vcs_setting) {
case DISABLE_VCS:
break;
case AUTO_VCS:
default:
- perp = rtw_get_ie23a(ie, _ERPINFO_IE_, &erp_len, ie_len);
- if (perp == NULL) {
+ p = cfg80211_find_ie(WLAN_EID_ERP_INFO, ie, ie_len);
+ if (!p)
pxmitpriv->vcs = NONE_VCS;
- } else {
- protection = (*(perp + 2)) & BIT(1);
+ else {
+ protection = (*(p + 2)) & BIT(1);
if (protection) {
if (pregistrypriv->vcs_type == RTS_CTS)
pxmitpriv->vcs = RTS_CTS;
/* DBG_8723A("enqueue, sq_len =%d, tim =%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
- update_beacon23a(padapter, _TIM_IE_, NULL, false);/* tx bc/mc packets after upate bcn */
+ /* tx bc/mc packets after upate bcn */
+ update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
/* spin_unlock_bh(&psta->sleep_q.lock); */
if (psta->sleepq_len == 1) {
/* upate BCN for TIM IE */
- update_beacon23a(padapter, _TIM_IE_, NULL, false);
+ update_beacon23a(padapter, WLAN_EID_TIM,
+ NULL, false);
}
}
}
if (update_mask)
- update_beacon23a(padapter, _TIM_IE_, NULL, false);
+ update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
}
void xmit_delivery_enabled_frames23a(struct rtw_adapter *padapter,
pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
/* upate BCN for TIM IE */
- update_beacon23a(padapter, _TIM_IE_, NULL, false);
+ update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
}
}
spin_unlock_bh(&pxmitpriv->lock);
return result;
}
-void hal_init_macaddr23a(struct rtw_adapter *adapter)
-{
- rtw_hal_set_hwreg23a(adapter, HW_VAR_MAC_ADDR,
- adapter->eeprompriv.mac_addr);
-}
-
/*
* C2H event format:
* Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID
/* delay_ms(40); */
rtw_write32(padapter, WCAMI, ulContent);
/* RT_TRACE(COMP_SEC, DBG_LOUD,
- ("CAM_empty_entry23a(): WRITE A4: %lx \n", ulContent));*/
+ ("rtl8723a_cam_empty_entry(): WRITE A4: %lx \n",
+ ulContent));*/
/* delay_ms(40); */
rtw_write32(padapter, RWCAM, ulCommand);
/* RT_TRACE(COMP_SEC, DBG_LOUD,
- ("CAM_empty_entry23a(): WRITE A0: %lx \n", ulCommand));*/
+ ("rtl8723a_cam_empty_entry(): WRITE A0: %lx \n",
+ ulCommand));*/
}
}
rtw_write32(padapter, RWCAM, BIT(31) | BIT(30));
}
-void rtl8723a_cam_write(struct rtw_adapter *padapter, u32 val1, u32 val2)
+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;
+ }
- rtw_write32(padapter, WCAMI, val1);
+ rtw_write32(padapter, WCAMI, val);
+ cmd = CAM_POLLINIG | CAM_WRITE | (addr + j);
+ rtw_write32(padapter, RWCAM, cmd);
- cmd = CAM_POLLINIG | CAM_WRITE | val2;
- rtw_write32(padapter, RWCAM, cmd);
+ /* DBG_8723A("%s => cam write: %x, %x\n", __func__, cmd, val);*/
+ }
}
void rtl8723a_fifo_cleanup(struct rtw_adapter *padapter)
}
}
-void rtl8723a_set_apfm_on_mac(struct rtw_adapter *padapter, u8 val)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- pHalData->bMacPwrCtrlOn = val;
- DBG_8723A("%s: bMacPwrCtrlOn =%d\n", __func__, pHalData->bMacPwrCtrlOn);
-}
-
void rtl8723a_bcn_valid(struct rtw_adapter *padapter)
{
/* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2,
rtw_read8(padapter, REG_TDECTRL + 2) | BIT0);
}
-void rtl8723a_set_tx_pause(struct rtw_adapter *padapter, u8 pause)
+bool rtl8723a_get_bcn_valid(struct rtw_adapter *padapter)
{
- rtw_write8(padapter, REG_TXPAUSE, pause);
+ bool retval;
+
+ retval = (rtw_read8(padapter, REG_TDECTRL + 2) & BIT0) ? true : false;
+
+ return retval;
}
void rtl8723a_set_beacon_interval(struct rtw_adapter *padapter, u16 interval)
}
}
-void rtl8723a_odm_support_ability_write(struct rtw_adapter *padapter, u32 val)
+void rtl8723a_odm_support_ability_restore(struct rtw_adapter *padapter)
{
struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- pHalData->odmpriv.SupportAbility = val;
+ pHalData->odmpriv.SupportAbility = pHalData->odmpriv.BK_SupportAbility;
}
-void rtl8723a_odm_support_ability_backup(struct rtw_adapter *padapter, u8 val)
+void rtl8723a_odm_support_ability_backup(struct rtw_adapter *padapter)
{
struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- if (val) /* save dm flag */
- pHalData->odmpriv.BK_SupportAbility =
- pHalData->odmpriv.SupportAbility;
- else /* restore dm flag */
- pHalData->odmpriv.SupportAbility =
- pHalData->odmpriv.BK_SupportAbility;
+ pHalData->odmpriv.BK_SupportAbility = pHalData->odmpriv.SupportAbility;
}
void rtl8723a_odm_support_ability_set(struct rtw_adapter *padapter, u32 val)
{
rtw_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 = rtw_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 = rtw_read32(padapter, REG_HGQ_INFORMATION);
+
+ return ((hgq & 0x0000ff00) == 0) ? true : false;
+}
return status;
}
-void rtw_hal_set_hwreg23a(struct rtw_adapter *padapter, u8 variable, u8 *val)
-{
- if (padapter->HalFunc.SetHwRegHandler)
- padapter->HalFunc.SetHwRegHandler(padapter, variable, val);
-}
-
-void rtw23a_hal_get_hwreg(struct rtw_adapter *padapter, u8 variable, u8 *val)
-{
- if (padapter->HalFunc.GetHwRegHandler)
- padapter->HalFunc.GetHwRegHandler(padapter, variable, val);
-}
-
u8 rtw_hal_set_def_var23a(struct rtw_adapter *padapter, enum hal_def_variable eVariable, void *pValue)
{
if (padapter->HalFunc.SetHalDefVarHandler)
}
-u8 rtw_hal_intf_ps_func23a(struct rtw_adapter *padapter, enum hal_intf_ps_func efunc_id, u8 *val)
-{
- if (padapter->HalFunc.interface_ps_func)
- return padapter->HalFunc.interface_ps_func(padapter, efunc_id, val);
- return _FAIL;
-}
-
s32 rtw_hal_xmit23aframe_enqueue(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe)
{
if (padapter->HalFunc.hal_xmitframe_enqueue)
padapter->HalFunc.Add_RateATid(padapter, bitmap, arg, rssi_level);
}
-/* Start specifical interface thread */
-void rtw_hal_start_thread23a(struct rtw_adapter *padapter)
-{
- if (padapter->HalFunc.run_thread)
- padapter->HalFunc.run_thread(padapter);
-}
-/* Start specifical interface thread */
-void rtw_hal_stop_thread23a(struct rtw_adapter *padapter)
-{
- if (padapter->HalFunc.cancel_thread)
- padapter->HalFunc.cancel_thread(padapter);
-}
-
-u32 rtw_hal_read_bbreg23a(struct rtw_adapter *padapter, u32 RegAddr, u32 BitMask)
-{
- u32 data = 0;
- if (padapter->HalFunc.read_bbreg)
- data = padapter->HalFunc.read_bbreg(padapter, RegAddr, BitMask);
- return data;
-}
-void rtw_hal_write_bbreg23a(struct rtw_adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data)
-{
- if (padapter->HalFunc.write_bbreg)
- padapter->HalFunc.write_bbreg(padapter, RegAddr, BitMask, Data);
-}
-
u32 rtw_hal_read_rfreg23a(struct rtw_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask)
{
u32 data = 0;
enum hci_status status = HCI_STATUS_SUCCESS;
struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 bFilterOutNonAssociatedBSSID = true;
if (!pBtHciInfo->bInTestMode) {
RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Not in Test mode, return status = HCI_STATUS_CMD_DISALLOW\n"));
del_timer_sync(&pBTInfo->BTTestSendPacketTimer);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_CHECK_BSSID, (u8 *)(&bFilterOutNonAssociatedBSSID));
+ rtl8723a_check_bssid(padapter, true);
/* send command complete event here when all data are received. */
{
jiffies + msecs_to_jiffies(50));
RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("TX Single Test \n"));
} else if (pBtHciInfo->TestScenario == 0x02) {
- u8 bFilterOutNonAssociatedBSSID = false;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_CHECK_BSSID, (u8 *)(&bFilterOutNonAssociatedBSSID));
+ rtl8723a_check_bssid(padapter, false);
RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Receive Frame Test \n"));
}
if (padapter->HalFunc.UpdateRAMaskHandler)
padapter->HalFunc.UpdateRAMaskHandler(padapter, MAX_FW_SUPPORT_MACID_NUM-1-EntryNum, 0);
- rtw_hal_set_hwreg23a(padapter, HW_VAR_BASIC_RATE, padapter->mlmepriv.cur_network.network.SupportedRates);
+ HalSetBrateCfg23a(padapter, padapter->mlmepriv.cur_network.network.SupportedRates);
BTDM_SetFwChnlInfo(padapter, RT_MEDIA_CONNECT);
break;
default:
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]));
+ 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))) {
+ 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);
rtw_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"));
+ 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 {
+ if (true == pBtCoex->bC2hBtInquiryPage)
+ btdm_1AntSetPSTDMA(padapter, false, 0,
+ true, 32);
+ else {
#ifdef BTCOEX_CMCC_TEST
- btdm_1AntSetPSTDMA(padapter, false, 0, true, 23);
+ btdm_1AntSetPSTDMA(padapter, false, 0,
+ true, 23);
#else /* !BTCOEX_CMCC_TEST */
- btdm_1AntSetPSTDMA(padapter, false, 0, false, 8);
+ btdm_1AntSetPSTDMA(padapter, false, 0,
+ false, 8);
rtw_write32(padapter, 0x6c0, 0x5a5a5a5a);
rtw_write32(padapter, 0x6c4, 0x5a5a5a5a);
#endif /* !BTCOEX_CMCC_TEST */
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"));
+ 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"));
+ 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"));
+ 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"));
+ 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));
+ 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)
+static void
+btdm_1AntUpdateHalRAMask(struct rtw_adapter *padapter, u32 mac_id, u32 filter)
{
u8 init_rate = 0;
u8 raid;
u32 mask;
u8 shortGIrate = false;
- int supportRateNum = 0;
+ int supportRateNum = 0;
struct sta_info *psta;
struct hal_data_8723a *pHalData;
struct dm_priv *pdmpriv;
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));
+ RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, MACID =%d, filter = 0x%08x!!\n",
+ __func__, mac_id, filter));
pHalData = GET_HAL_DATA(padapter);
pdmpriv = &pHalData->dmpriv;
cur_network = &pmlmeinfo->network;
if (mac_id >= NUM_STA) { /* CAM_SIZE */
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, MACID =%d illegal!!\n", __func__, mac_id));
+ RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, MACID =%d illegal!!\n",
+ __func__, mac_id));
return;
}
psta = pmlmeinfo->FW_sta_info[mac_id].psta;
- if (psta == NULL) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, Can't find station!!\n", __func__));
+ if (!psta) {
+ RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, Can't find station!!\n",
+ __func__));
return;
}
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_caps):0;
+ 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_caps):0;
if (support_short_GI23a(padapter, &pmlmeinfo->HT_caps))
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);
+ 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);
+ 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);
arg |= BIT(5);
RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], Update FW RAID entry, MASK = 0x%08x, arg = 0x%02x\n",
- mask, arg));
+ ("[BTCoex], Update FW RAID entry, MASK = 0x%08x, "
+ "arg = 0x%02x\n", mask, arg));
rtl8723a_set_raid_cmd(padapter, mask, arg);
} else {
pdmpriv->INIDATA_RATE[mac_id] = init_rate;
}
-static void btdm_1AntUpdateHalRAMaskForSCO(struct rtw_adapter *padapter, u8 forceUpdate)
+static void
+btdm_1AntUpdateHalRAMaskForSCO(struct rtw_adapter *padapter, u8 forceUpdate)
{
struct btdm_8723a_1ant *pBtdm8723;
struct sta_priv *pstapriv;
pBtdm8723 = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant;
- if ((pBtdm8723->bRAChanged == true) && (forceUpdate == false))
+ if (pBtdm8723->bRAChanged == true && forceUpdate == false)
return;
pstapriv = &padapter->stapriv;
static void
btdm_1AntBTStateChangeHandler(struct rtw_adapter *padapter,
- enum bt_state_1ant oldState, enum bt_state_1ant newState)
+ enum bt_state_1ant oldState,
+ enum bt_state_1ant newState)
{
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT state change, %s => %s\n", BtStateString[oldState], BtStateString[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 */
btdm_1AntRecoverHalRAMask(padapter);
}
} else {
- GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bRAChanged = false;
+ 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 *pHalData = GET_HAL_DATA(padapter);
- pHalData->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCnt = 0;
- pHalData->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCntForSCO = 0;
+ 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 *pHalData = GET_HAL_DATA(padapter);
- pHalData->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCntForSCO = 0;
+ struct hal_data_8723a *Hal = GET_HAL_DATA(padapter);
+ Hal->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCntForSCO = 0;
}
/* Active 2Ant mechanism when BT Connected */
(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_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_SetSwRfRxLpfCorner(padapter,
+ BT_RF_RX_LPF_CORNER_RESUME);
BTDM_AGCTable(padapter, BT_AGCTABLE_OFF);
BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_OFF);
}
RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is disabled\n"));
if (BTDM_IsWifiConnectionExist(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is connected\n"));
+ 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);
+ 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);
+ 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"));
+ RTPRINT(FBT, BT_TRACE,
+ ("[BTCoex], wifi is disconnected\n"));
btdm_1AntSetPSTDMA(padapter, false, 0, false, 9);
}
RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is enabled\n"));
if (BTDM_IsWifiConnectionExist(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is connected\n"));
+ 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"));
+ RTPRINT(FBT, BT_TRACE,
+ ("[BTCoex], wifi is disconnected\n"));
- /* Antenna switch at BT side(0x870 = 0x300, 0x860 = 0x210) after PSTDMA off */
+ /* 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);
+ btdm_1AntBTStateChangeHandler(padapter, pBtCoex8723->prec2hBtInfo,
+ pBtCoex8723->c2hBtInfo);
pBtCoex8723->prec2hBtInfo = pBtCoex8723->c2hBtInfo;
}
-void BTDM_1AntSignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi, u8 *rssi_bt)
+void BTDM_1AntSignalCompensation(struct rtw_adapter *padapter,
+ u8 *rssi_wifi, u8 *rssi_bt)
{
struct hal_data_8723a *pHalData;
struct btdm_8723a_1ant *pBtdm8723;
}
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));
+ 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));
+ 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;
}
}
{
RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for halt\n"));
- GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bWiFiHalt = true;
+ GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bWiFiHalt =
+ true;
btdm_1AntWifiParaAdjust(padapter, false);
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;
+ GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bWiFiHalt =
+ true;
btdm_1AntSetPSTDMA(padapter, false, 0, false, 8);
/*btdm_1AntPsTdma(padapter, false, 8); */
{
struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for associate, type =%d\n", type));
+ RTPRINT(FBT, BT_TRACE,
+ ("\n[BTCoex], 1Ant for associate, type =%d\n", type));
if (type) {
rtl8723a_CheckAntenna_Selection(padapter);
- if (BT_IsBtDisabled(padapter)) {
+ if (BT_IsBtDisabled(padapter))
btdm_1AntSetPSTDMA(padapter, false, 0, false, 9);
- } else {
+ else {
struct bt_coexist_8723a *pBtCoex;
u8 BtState;
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);
+ 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);
rtw_write32(padapter, 0x6c0, 0x5a5a5a5a);
rtw_write32(padapter, 0x6c4, 0x5a5a5a5a);
- } else if ((BtState == BT_INFO_STATE_ACL_ONLY_BUSY) ||
- (BtState == BT_INFO_STATE_ACL_INQ_OR_PAG)) {
+ } 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);
+ btdm_1AntSetPSTDMA(padapter, false, 0,
+ true, 35);
else
- btdm_1AntSetPSTDMA(padapter, false, 0, true, 29);
+ btdm_1AntSetPSTDMA(padapter, false, 0,
+ true, 29);
}
}
} else {
pBtCoex = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723;
- RTPRINT(FBT, BT_TRACE, ("\n\n[BTCoex]******************************\n"));
+ 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))
+ 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__); */
+ /* DBG_8723A("%s rtl8723a_DeinitAntenna_Selection\n",
+ __func__); */
rtl8723a_DeinitAntenna_Selection(padapter);
btdm_1AntBtCoexistHandler(padapter);
pBtCoex->btdm1Ant.bRAChanged = false;
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]));
+ 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);
}
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]));
+ 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 ((BtState == BT_INFO_STATE_SCO_ONLY_BUSY) ||
(BtState == BT_INFO_STATE_ACL_SCO_BUSY)) {
if (pBtCoex->bC2hBtInquiryPage) {
- btdm_1AntSetPSTDMA(padapter, false, 0, true, 32);
+ btdm_1AntSetPSTDMA(padapter, false, 0,
+ true, 32);
} else {
- padapter->pwrctrlpriv.btcoex_rfon = true;
- btdm_1AntSetPSTDMA(padapter, true, 0, true, 33);
+ padapter->pwrctrlpriv.btcoex_rfon =
+ true;
+ btdm_1AntSetPSTDMA(padapter, true, 0,
+ true, 33);
}
} else if (true == pBtCoex->bC2hBtInquiryPage) {
padapter->pwrctrlpriv.btcoex_rfon = true;
} 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);
+ btdm_1AntSetPSTDMA(padapter, true, 0,
+ true, 34);
else
- btdm_1AntSetPSTDMA(padapter, true, 0, true, 4);
+ btdm_1AntSetPSTDMA(padapter, true, 0,
+ true, 4);
} else {
padapter->pwrctrlpriv.btcoex_rfon = true;
btdm_1AntSetPSTDMA(padapter, true, 0, true, 5);
pBtCoex->bC2hBtInquiryPage = false;
btState &= ~BIT(2);
- if (!(btState & BIT(0))) {
+ if (!(btState & BIT(0)))
pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION;
- } else {
- if (btState == 0x1) {
+ else {
+ if (btState == 0x1)
pBtCoex->c2hBtInfo = BT_INFO_STATE_CONNECT_IDLE;
- } else if (btState == 0x9) {
+ else if (btState == 0x9) {
if (pBtCoex->bC2hBtInquiryPage == true)
- pBtCoex->c2hBtInfo = BT_INFO_STATE_ACL_INQ_OR_PAG;
+ pBtCoex->c2hBtInfo =
+ BT_INFO_STATE_ACL_INQ_OR_PAG;
else
- pBtCoex->c2hBtInfo = BT_INFO_STATE_ACL_ONLY_BUSY;
+ pBtCoex->c2hBtInfo =
+ BT_INFO_STATE_ACL_ONLY_BUSY;
pBtMgnt->ExtConfig.bBTBusy = true;
} else if (btState == 0x3) {
pBtCoex->c2hBtInfo = BT_INFO_STATE_SCO_ONLY_BUSY;
} else if (btState == 0xb) {
pBtCoex->c2hBtInfo = BT_INFO_STATE_ACL_SCO_BUSY;
pBtMgnt->ExtConfig.bBTBusy = true;
- } else {
+ } else
pBtCoex->c2hBtInfo = BT_INFO_STATE_MAX;
- }
if (pBtMgnt->ExtConfig.bBTBusy)
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_IDLE;
+ 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 (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;
}
if (check_fwstate(pmlmepriv, WIFI_SITE_MONITOR)) {
/* already done in BTDM_1AntForScan() */
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is under scan progress!!\n"));
+ 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"));
+ RTPRINT(FBT, BT_TRACE,
+ ("[BTCoex], wifi is under link progress!!\n"));
return;
}
pBtAssocEntry->HwCAMIndex = BT_HWCAM_STAR + EntryNum;
usConfig = CAM_VALID | (CAM_AES << 2);
- write_cam23a(padapter, pBtAssocEntry->HwCAMIndex, usConfig, pBtAssocEntry->BTRemoteMACAddr, pBtAssocEntry->PTK + TKIP_ENC_KEY_POS);
+ rtl8723a_cam_write(padapter, pBtAssocEntry->HwCAMIndex, usConfig,
+ pBtAssocEntry->BTRemoteMACAddr,
+ pBtAssocEntry->PTK + TKIP_ENC_KEY_POS);
}
void HALBT_RemoveKey(struct rtw_adapter *padapter, u8 EntryNum)
if (pBTinfo->BtAsocEntry[EntryNum].HwCAMIndex != 0) {
/* ToDo : add New HALBT_RemoveKey function !! */
- if (pBtAssocEntry->HwCAMIndex >= BT_HWCAM_STAR && pBtAssocEntry->HwCAMIndex < HALF_CAM_ENTRY)
- CAM_empty_entry23a(padapter, pBtAssocEntry->HwCAMIndex);
+ if (pBtAssocEntry->HwCAMIndex >= BT_HWCAM_STAR &&
+ pBtAssocEntry->HwCAMIndex < HALF_CAM_ENTRY)
+ rtl8723a_cam_empty_entry(padapter,
+ pBtAssocEntry->HwCAMIndex);
pBTinfo->BtAsocEntry[EntryNum].HwCAMIndex = 0;
}
}
#include <osdep_service.h>
#include <drv_types.h>
#include <recv_osdep.h>
-#include <cmd_osdep.h>
#include <mlme_osdep.h>
#include <rtw_ioctl_set.h>
#include <rtl8723a_hal.h>
static void ConstructBeacon(struct rtw_adapter *padapter, u8 *pframe, u32 *pLength)
{
struct ieee80211_hdr *pwlanhdr;
- u16 *fctrl;
+ __le16 *fctrl;
u32 rate_len, pktlen;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
/* below for ad-hoc mode */
/* SSID */
- pframe = rtw_set_ie23a(pframe, _SSID_IE_, cur_network->Ssid.ssid_len,
- cur_network->Ssid.ssid, &pktlen);
+ 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, _SUPPORTEDRATES_IE_, ((rate_len > 8) ?
+ 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, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pktlen);
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
+ &cur_network->Configuration.DSConfig, &pktlen);
if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
u32 ATIMWindow;
/* IBSS Parameter Set... */
/* ATIMWindow = cur->Configuration.ATIMWindow; */
ATIMWindow = 0;
- pframe = rtw_set_ie23a(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
+ 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, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
+ pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
+ (rate_len - 8),
+ (cur_network->SupportedRates + 8),
+ &pktlen);
/* todo:HT for adhoc */
static void ConstructPSPoll(struct rtw_adapter *padapter, u8 *pframe, u32 *pLength)
{
struct ieee80211_hdr *pwlanhdr;
- u16 *fctrl;
+ __le16 *fctrl;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
u8 bForcePowerSave)
{
struct ieee80211_hdr *pwlanhdr;
- u16 *fctrl;
+ __le16 *fctrl;
u32 pktlen;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_network *cur_network = &pmlmepriv->cur_network;
static void ConstructProbeRsp(struct rtw_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, bool bHideSSID)
{
struct ieee80211_hdr *pwlanhdr;
- u16 *fctrl;
+ __le16 *fctrl;
u8 *mac, *bssid;
u32 pktlen;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
}
}
#endif
-
-#ifdef CONFIG_8723AU_P2P
-void rtl8723a_set_p2p_ps_offload_cmd(struct rtw_adapter *padapter, u8 p2p_ps_state)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- struct P2P_PS_Offload_t *p2p_ps_offload = &pHalData->p2p_ps_offload;
- u8 i;
-
- switch (p2p_ps_state) {
- case P2P_PS_DISABLE:
- DBG_8723A("P2P_PS_DISABLE \n");
- memset(p2p_ps_offload, 0, 1);
- break;
- case P2P_PS_ENABLE:
- DBG_8723A("P2P_PS_ENABLE \n");
- /* update CTWindow value. */
- if (pwdinfo->ctwindow > 0) {
- p2p_ps_offload->CTWindow_En = 1;
- rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow);
- }
-
- /* hw only support 2 set of NoA */
- for (i = 0; i < pwdinfo->noa_num; i++) {
- /* To control the register setting for which NOA */
- rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4));
- if (i == 0)
- p2p_ps_offload->NoA0_En = 1;
- else
- p2p_ps_offload->NoA1_En = 1;
-
- /* config P2P NoA Descriptor Register */
- rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]);
-
- rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]);
-
- rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]);
-
- rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]);
- }
-
- if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
- /* rst p2p circuit */
- rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4));
-
- p2p_ps_offload->Offload_En = 1;
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- p2p_ps_offload->role = 1;
- p2p_ps_offload->AllStaSleep = 0;
- } else {
- p2p_ps_offload->role = 0;
- }
-
- p2p_ps_offload->discovery = 0;
- }
- break;
- case P2P_PS_SCAN:
- DBG_8723A("P2P_PS_SCAN \n");
- p2p_ps_offload->discovery = 1;
- break;
- case P2P_PS_SCAN_DONE:
- DBG_8723A("P2P_PS_SCAN_DONE \n");
- p2p_ps_offload->discovery = 0;
- pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
- break;
- default:
- break;
- }
-
- FillH2CCmd(padapter, P2P_PS_OFFLOAD_EID, 1, (u8 *)p2p_ps_offload);
-}
-#endif /* CONFIG_8723AU_P2P */
return;
}
- rtw_signal_process(padapter->pid[0], SIGUSR1);
+ kill_pid(find_vpid(padapter->pid[0]), SIGUSR1, 1);
}
}
goto skip_dm;
bFwCurrentInPSMode = Adapter->pwrctrlpriv.bFwCurrentInPSMode;
- rtw23a_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake));
-
-#ifdef CONFIG_8723AU_P2P
- /* Fw is under p2p powersaving mode, driver should stop dynamic mechanism. */
- /* modifed by thomas. 2011.06.11. */
- if (Adapter->wdinfo.p2p_ps_mode)
- bFwPSAwake = false;
-#endif /* CONFIG_8723AU_P2P */
+ bFwPSAwake = rtl8723a_get_fwlps_rf_on(Adapter);
if ((hw_init_completed) && ((!bFwCurrentInPSMode) && bFwPSAwake)) {
/* Calculate Tx/Rx statistics. */
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. */
EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total);
used = eFuse_Addr - 1;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&used);
+ pHalData->EfuseUsedBytes = used;
kfree(efuseTbl);
}
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. */
EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total);
used = (EFUSE_BT_REAL_BANK_CONTENT_LEN * (bank - 1)) + eFuse_Addr - 1;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *) &used);
+ pHalData->BTEfuseUsedBytes = used;
exit:
kfree(efuseTbl);
u16 efuse_addr = 0;
u8 hoffset = 0, hworden = 0;
u8 efuse_data, word_cnts = 0;
+ struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- rtw23a_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *) &efuse_addr);
+ efuse_addr = pHalData->EfuseUsedBytes;
DBG_8723A("%s: start_efuse_addr = 0x%X\n", __func__, efuse_addr);
efuse_addr += (word_cnts * 2) + 1;
}
- rtw_hal_set_hwreg23a(padapter, HW_VAR_EFUSE_BYTES, (u8 *) &efuse_addr);
+ pHalData->EfuseUsedBytes = efuse_addr;
DBG_8723A("%s: CurrentSize =%d\n", __func__, efuse_addr);
u8 hoffset = 0, hworden = 0;
u8 efuse_data, word_cnts = 0;
u16 retU2 = 0;
+ struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- rtw23a_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *) &btusedbytes);
+ btusedbytes = pHalData->BTEfuseUsedBytes;
efuse_addr = (u16) ((btusedbytes % EFUSE_BT_REAL_BANK_CONTENT_LEN));
startBank = (u8) (1 + (btusedbytes / EFUSE_BT_REAL_BANK_CONTENT_LEN));
}
retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
- rtw_hal_set_hwreg23a(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&retU2);
+ pHalData->BTEfuseUsedBytes = retU2;
DBG_8723A("%s: CurrentSize =%d\n", __func__, retU2);
return retU2;
hal_EfusePartialWriteCheck(struct rtw_adapter *padapter, u8 efuseType,
u16 *pAddr, struct pg_pkt_struct *pTargetPkt)
{
+ struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
u8 bRet = false;
u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0;
u8 efuse_data = 0;
EFUSE_GetEfuseDefinition23a(padapter, efuseType,
TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max);
- if (efuseType == EFUSE_WIFI) {
- rtw23a_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES,
- (u8 *) &startAddr);
- } else {
- rtw23a_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES,
- (u8 *) &startAddr);
- }
+ if (efuseType == EFUSE_WIFI)
+ startAddr = pHalData->EfuseUsedBytes;
+ else
+ startAddr = pHalData->BTEfuseUsedBytes;
+
startAddr %= efuse_max;
while (1) {
&rtl8723a_SetBeaconRelatedRegisters;
pHalFunc->Add_RateATid = &rtl8723a_add_rateatid;
- pHalFunc->run_thread = &rtl8723a_start_thread;
- pHalFunc->cancel_thread = &rtl8723a_stop_thread;
- pHalFunc->read_bbreg = &PHY_QueryBBReg;
- pHalFunc->write_bbreg = &PHY_SetBBReg;
pHalFunc->read_rfreg = &PHY_QueryRFReg;
pHalFunc->write_rfreg = &PHY_SetRFReg;
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 (!pDevice->RegUsbSS) */
/* If we want to SS mode, we can not reset 8051. */
if (rtw_read8(padapter, REG_MCUFWDL) & BIT1) {
/* IF fw in RAM code, do reset */
rtl8723a_cal_txdesc_chksum(ptxdesc);
}
-static void hw_var_set_opmode(struct rtw_adapter *padapter, u8 mode)
+void hw_var_set_opmode(struct rtw_adapter *padapter, u8 mode)
{
u8 val8;
rtw_write8(padapter, MSR, val8);
}
-static void hw_var_set_macaddr(struct rtw_adapter *padapter, u8 *val)
+void hw_var_set_macaddr(struct rtw_adapter *padapter, u8 *val)
{
u8 idx = 0;
u32 reg_macid;
rtw_write8(padapter, (reg_macid + idx), val[idx]);
}
-static void hw_var_set_bssid(struct rtw_adapter *padapter, u8 *val)
+void hw_var_set_bssid(struct rtw_adapter *padapter, u8 *val)
{
u8 idx = 0;
u32 reg_bssid;
rtw_write8(padapter, (reg_bssid + idx), val[idx]);
}
-static void hw_var_set_correct_tsf(struct rtw_adapter *padapter)
+void hw_var_set_correct_tsf(struct rtw_adapter *padapter)
{
u64 tsf;
u32 reg_tsftr;
/* tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue %
(pmlmeinfo->bcn_interval*1024)) - 1024; us */
tsf = pmlmeext->TSFValue -
- rtw_modular6423a(pmlmeext->TSFValue,
- (pmlmeinfo->bcn_interval * 1024)) - 1024; /* us */
+ do_div(pmlmeext->TSFValue,
+ (pmlmeinfo->bcn_interval * 1024)) - 1024; /* us */
if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
ResumeTxBeacon(padapter);
}
-static void hw_var_set_mlme_disconnect(struct rtw_adapter *padapter)
+void hw_var_set_mlme_disconnect(struct rtw_adapter *padapter)
{
/* reject all data frames */
rtw_write16(padapter, REG_RXFLTMAP2, 0);
SetBcnCtrlReg23a(padapter, DIS_TSF_UDT, 0);
}
-static void hw_var_set_mlme_join(struct rtw_adapter *padapter, u8 type)
+void hw_var_set_mlme_join(struct rtw_adapter *padapter, u8 type)
{
u8 RetryLimit = 0x30;
#endif
}
-void SetHwReg8723A(struct rtw_adapter *padapter, u8 variable, u8 *val)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u32 *val32 = (u32 *)val;
-
- switch (variable) {
- case HW_VAR_MEDIA_STATUS:
- rtl8723a_set_media_status(padapter, *val);
- break;
-
- case HW_VAR_MEDIA_STATUS1:
- rtl8723a_set_media_status1(padapter, *val);
- break;
-
- case HW_VAR_SET_OPMODE:
- hw_var_set_opmode(padapter, *val);
- break;
-
- case HW_VAR_MAC_ADDR:
- hw_var_set_macaddr(padapter, val);
- break;
-
- case HW_VAR_BSSID:
- hw_var_set_bssid(padapter, val);
- break;
-
- case HW_VAR_BASIC_RATE:
- HalSetBrateCfg23a(padapter, val);
- break;
-
- case HW_VAR_TXPAUSE:
- rtl8723a_set_tx_pause(padapter, *val);
- break;
-
- case HW_VAR_BCN_FUNC:
- rtl8723a_set_bcn_func(padapter, *val);
- break;
-
- case HW_VAR_CORRECT_TSF:
- hw_var_set_correct_tsf(padapter);
- break;
-
- case HW_VAR_CHECK_BSSID:
- rtl8723a_check_bssid(padapter, *val);
- break;
-
- case HW_VAR_MLME_DISCONNECT:
- hw_var_set_mlme_disconnect(padapter);
- break;
-
- case HW_VAR_MLME_SITESURVEY:
- rtl8723a_mlme_sitesurvey(padapter, *val);
- break;
-
- case HW_VAR_MLME_JOIN:
- hw_var_set_mlme_join(padapter, *val);
- break;
-
- case HW_VAR_ON_RCR_AM:
- rtl8723a_on_rcr_am(padapter);
- break;
-
- case HW_VAR_OFF_RCR_AM:
- rtl8723a_off_rcr_am(padapter);
- break;
-
- case HW_VAR_BEACON_INTERVAL:
- rtl8723a_set_beacon_interval(padapter, *((u16 *) val));
- break;
-
- case HW_VAR_SLOT_TIME:
- rtl8723a_set_slot_time(padapter, *val);
- break;
-
- case HW_VAR_RESP_SIFS:
- rtl8723a_set_resp_sifs(padapter, val[0], val[1],
- val[2], val[3]);
- break;
-
- case HW_VAR_ACK_PREAMBLE:
- rtl8723a_ack_preamble(padapter, *val);
- break;
-
- case HW_VAR_SEC_CFG:
- rtl8723a_set_sec_cfg(padapter, *val);
- break;
-
- case HW_VAR_DM_FLAG:
- rtl8723a_odm_support_ability_write(padapter, *val32);
- break;
- case HW_VAR_DM_FUNC_OP:
- rtl8723a_odm_support_ability_backup(padapter, *val);
- break;
- case HW_VAR_DM_FUNC_SET:
- rtl8723a_odm_support_ability_set(padapter, *val32);
- break;
-
- case HW_VAR_DM_FUNC_CLR:
- rtl8723a_odm_support_ability_clr(padapter, *val32);
- break;
-
- case HW_VAR_CAM_EMPTY_ENTRY:
- rtl8723a_cam_empty_entry(padapter, *val);
- break;
-
- case HW_VAR_CAM_INVALID_ALL:
- rtl8723a_cam_invalid_all(padapter);
- break;
-
- case HW_VAR_CAM_WRITE:
- rtl8723a_cam_write(padapter, val32[0], val32[1]);
- break;
-
- case HW_VAR_AC_PARAM_VO:
- rtl8723a_set_ac_param_vo(padapter, *val32);
- break;
-
- case HW_VAR_AC_PARAM_VI:
- rtl8723a_set_ac_param_vi(padapter, *val32);
- break;
-
- case HW_VAR_AC_PARAM_BE:
- rtl8723a_set_ac_param_be(padapter, *val32);
- break;
-
- case HW_VAR_AC_PARAM_BK:
- rtl8723a_set_ac_param_bk(padapter, *val32);
- break;
-
- case HW_VAR_ACM_CTRL:
- rtl8723a_set_acm_ctrl(padapter, *val);
- break;
-
- case HW_VAR_AMPDU_MIN_SPACE:
- rtl8723a_set_ampdu_min_space(padapter, *val);
- break;
-
- case HW_VAR_AMPDU_FACTOR:
- rtl8723a_set_ampdu_factor(padapter, *val);
- break;
-
- case HW_VAR_RXDMA_AGG_PG_TH:
- rtl8723a_set_rxdma_agg_pg_th(padapter, *val);
- break;
-
- case HW_VAR_H2C_FW_PWRMODE:
- rtl8723a_set_FwPwrMode_cmd(padapter, *val);
- break;
-
- case HW_VAR_H2C_FW_JOINBSSRPT:
- rtl8723a_set_FwJoinBssReport_cmd(padapter, *val);
- break;
-
-#ifdef CONFIG_8723AU_P2P
- case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
- rtl8723a_set_p2p_ps_offload_cmd(padapter, *val);
- break;
-#endif /* CONFIG_8723AU_P2P */
-
- case HW_VAR_INITIAL_GAIN:
- rtl8723a_set_initial_gain(padapter, *val32);
- break;
- case HW_VAR_EFUSE_BYTES:
- pHalData->EfuseUsedBytes = *((u16 *) val);
- break;
- case HW_VAR_EFUSE_BT_BYTES:
- pHalData->BTEfuseUsedBytes = *((u16 *) val);
- break;
- case HW_VAR_FIFO_CLEARN_UP:
- rtl8723a_fifo_cleanup(padapter);
- break;
- case HW_VAR_CHECK_TXBUF:
- break;
- case HW_VAR_APFM_ON_MAC:
- rtl8723a_set_apfm_on_mac(padapter, *val);
- break;
-
- case HW_VAR_NAV_UPPER:
- rtl8723a_set_nav_upper(padapter, *val32);
- break;
- case HW_VAR_BCN_VALID:
- rtl8723a_bcn_valid(padapter);
- break;
- default:
- break;
- }
-
-}
-
-void GetHwReg8723A(struct rtw_adapter *padapter, u8 variable, u8 *val)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- switch (variable) {
- case HW_VAR_BASIC_RATE:
- *((u16 *) val) = pHalData->BasicRateSet;
- break;
-
- case HW_VAR_TXPAUSE:
- *val = rtw_read8(padapter, REG_TXPAUSE);
- break;
-
- case HW_VAR_BCN_VALID:
- /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */
- val[0] = (BIT0 & rtw_read8(padapter, REG_TDECTRL + 2)) ? true :
- false;
- break;
-
- case HW_VAR_RF_TYPE:
- *val = pHalData->rf_type;
- break;
-
- case HW_VAR_DM_FLAG:
- {
- struct dm_odm_t *podmpriv = &pHalData->odmpriv;
- *((u32 *) val) = podmpriv->SupportAbility;
- }
- break;
-
- case HW_VAR_FWLPS_RF_ON:
- {
- /* When we halt NIC, we should check if FW LPS is leave. */
- u32 valRCR;
-
- 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. */
- *val = true;
- } else {
- valRCR = rtw_read32(padapter, REG_RCR);
- valRCR &= 0x00070000;
- if (valRCR)
- *val = false;
- else
- *val = true;
- }
- }
- break;
- case HW_VAR_EFUSE_BYTES:
- *((u16 *) val) = pHalData->EfuseUsedBytes;
- break;
-
- case HW_VAR_EFUSE_BT_BYTES:
- *((u16 *) val) = pHalData->BTEfuseUsedBytes;
- break;
-
- case HW_VAR_APFM_ON_MAC:
- *val = pHalData->bMacPwrCtrlOn;
- break;
- case HW_VAR_CHK_HI_QUEUE_EMPTY:
- *val =
- ((rtw_read32(padapter, REG_HGQ_INFORMATION) & 0x0000ff00) ==
- 0) ? true : false;
- break;
- }
-}
-
#ifdef CONFIG_8723AU_BT_COEXIST
void rtl8723a_SingleDualAntennaDetection(struct rtw_adapter *padapter)
memcpy(dst_adapter->HalData, src_adapter->HalData,
dst_adapter->hal_data_sz);
}
-
-void rtl8723a_start_thread(struct rtw_adapter *padapter)
-{
-}
-
-void rtl8723a_stop_thread(struct rtw_adapter *padapter)
-{
-}
#include <mlme_osdep.h>
#include <linux/ip.h>
#include <linux/if_ether.h>
-#include <ethernet.h>
#include <usb_ops.h>
#include <wifi.h>
#include <rtl8723a_hal.h>
for (i = 0; i < NR_RECVBUFF; i++) {
INIT_LIST_HEAD(&precvbuf->list);
- res = rtw_os_recvbuf_resource_alloc23a(padapter, precvbuf);
- if (res == _FAIL)
+ precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!precvbuf->purb)
break;
precvbuf->adapter = padapter;
precvbuf = (struct recv_buf *)precvpriv->precv_buf;
for (i = 0; i < NR_RECVBUFF; i++) {
- rtw_os_recvbuf_resource_free23a(padapter, precvbuf);
+ usb_free_urb(precvbuf->purb);
+
+ if (precvbuf->pskb)
+ dev_kfree_skb_any(precvbuf->pskb);
+
precvbuf++;
}
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 report;
+ struct recv_stat_cpu report;
struct rxreport_8723a *prxreport;
report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
struct registry_priv *pregistrypriv = &Adapter->registrypriv;
- u32 NavUpper = WiFiNavUpperUs;
unsigned long init_start_time = jiffies;
_InitDriverInfoSize(Adapter, DRVINFO_SZ);
_InitInterrupt(Adapter);
- hal_init_macaddr23a(Adapter);/* set mac_address */
+ hw_var_set_macaddr(Adapter, Adapter->eeprompriv.mac_addr);
_InitNetworkType(Adapter);/* set msr */
_InitWMACSetting(Adapter);
_InitAdaptiveCtrl(Adapter);
rtl8723a_InitHalDm(Adapter);
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC31);
- rtw_hal_set_hwreg23a(Adapter, HW_VAR_NAV_UPPER, (u8 *)&NavUpper);
+ rtl8723a_set_nav_upper(Adapter, WiFiNavUpperUs);
/* 2011/03/09 MH debug only, UMC-B cut pass 2500 S5 test, but we need to fin root cause. */
if (((rtw_read32(Adapter, rFPGA0_RFMOD) & 0xFF000000) != 0x83000000)) {
u8 i;
struct recv_buf *precvbuf;
uint status;
- struct intf_hdl *pintfhdl = &Adapter->iopriv.intf;
+ struct _io_ops *io_ops = &Adapter->io_ops;
struct recv_priv *precvpriv = &Adapter->recvpriv;
- u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
+ u32 (*_read_port)(struct rtw_adapter *padapter, u32 addr, u32 cnt,
struct recv_buf *rbuf);
- u32 (*_read_interrupt)(struct intf_hdl *pintfhdl, u32 addr);
+ u32 (*_read_interrupt)(struct rtw_adapter *padapter, u32 addr);
struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- _read_port = pintfhdl->io_ops._read_port;
+ _read_port = io_ops->_read_port;
status = _SUCCESS;
/* issue Rx irp to receive data */
precvbuf = (struct recv_buf *)precvpriv->precv_buf;
for (i = 0; i < NR_RECVBUFF; i++) {
- if (_read_port(pintfhdl, precvpriv->ff_hwaddr, 0, precvbuf) ==
+ if (_read_port(Adapter, precvpriv->ff_hwaddr, 0, precvbuf) ==
false) {
RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
("usb_rx_init: usb_read_port error\n"));
precvbuf++;
precvpriv->free_recv_buf_queue_cnt--;
}
- _read_interrupt = pintfhdl->io_ops._read_interrupt;
- if (_read_interrupt(pintfhdl, RECV_INT_IN_ADDR) == false) {
+ _read_interrupt = io_ops->_read_interrupt;
+ if (_read_interrupt(Adapter, RECV_INT_IN_ADDR) == false) {
RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
("usb_rx_init: usb_read_interrupt error\n"));
status = _FAIL;
_ReadAdapterInfo8723AU(Adapter);
}
-#define GPIO_DEBUG_PORT_NUM 0
-static void rtl8723au_trigger_gpio_0(struct rtw_adapter *padapter)
-{
- u32 gpioctrl;
- DBG_8723A("==> trigger_gpio_0...\n");
- rtw_write16_async(padapter, REG_GPIO_PIN_CTRL, 0);
- rtw_write8_async(padapter, REG_GPIO_PIN_CTRL+2, 0xFF);
- gpioctrl = (BIT(GPIO_DEBUG_PORT_NUM) << 24)|
- (BIT(GPIO_DEBUG_PORT_NUM) << 16);
- rtw_write32_async(padapter, REG_GPIO_PIN_CTRL, gpioctrl);
- gpioctrl |= (BIT(GPIO_DEBUG_PORT_NUM)<<8);
- rtw_write32_async(padapter, REG_GPIO_PIN_CTRL, gpioctrl);
- DBG_8723A("<=== trigger_gpio_0...\n");
-}
-
-/*
- * If variable not handled here,
- * some variables will be processed in SetHwReg8723A()
- */
-static void SetHwReg8723AU(struct rtw_adapter *Adapter, u8 variable, u8 *val)
-{
- switch (variable) {
- case HW_VAR_RXDMA_AGG_PG_TH:
- break;
- case HW_VAR_SET_RPWM:
- rtl8723a_set_rpwm(Adapter, *val);
- break;
- case HW_VAR_TRIGGER_GPIO_0:
- rtl8723au_trigger_gpio_0(Adapter);
- break;
- default:
- SetHwReg8723A(Adapter, variable, val);
- break;
- }
-
-}
-
-/*
- * If variable not handled here,
- * some variables will be processed in GetHwReg8723A()
- */
-static void GetHwReg8723AU(struct rtw_adapter *Adapter, u8 variable, u8 *val)
-{
- GetHwReg8723A(Adapter, variable, val);
-}
-
/* */
/* Description: */
/* Query setting of specified variable. */
rtl8723a_init_default_value(padapter);
}
-static u8 rtl8192cu_ps_func(struct rtw_adapter *Adapter,
- enum hal_intf_ps_func efunc_id, u8 *val)
-{
- return true;
-}
-
int rtl8723au_set_hal_ops(struct rtw_adapter *padapter)
{
struct hal_ops *pHalFunc = &padapter->HalFunc;
pHalFunc->init_default_value = &rtl8723au_init_default_value;
pHalFunc->intf_chip_configure = &rtl8723au_interface_configure;
pHalFunc->read_adapter_info = &ReadAdapterInfo8723AU;
- pHalFunc->SetHwRegHandler = &SetHwReg8723AU;
- pHalFunc->GetHwRegHandler = &GetHwReg8723AU;
pHalFunc->GetHalDefVarHandler = &GetHalDefVar8192CUsb;
pHalFunc->SetHalDefVarHandler = &SetHalDefVar8192CUsb;
pHalFunc->UpdateRAMaskHandler = &UpdateHalRAMask8192CUsb;
pHalFunc->hal_xmit = &rtl8723au_hal_xmit;
pHalFunc->mgnt_xmit = &rtl8723au_mgnt_xmit;
pHalFunc->hal_xmitframe_enqueue = &rtl8723au_hal_xmitframe_enqueue;
- pHalFunc->interface_ps_func = &rtl8192cu_ps_func;
rtl8723a_set_hal_ops(pHalFunc);
return 0;
}
#include <rtl8723a_hal.h>
#include <rtl8723a_recv.h>
-static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype)
+static int usbctrl_vendorreq(struct rtw_adapter *padapter, u8 request,
+ u16 value, u16 index, void *pdata, u16 len,
+ u8 requesttype)
{
- struct rtw_adapter *padapter = pintfhdl->padapter ;
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
struct usb_device *udev = pdvobjpriv->pusbdev;
return status;
}
-static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
+static u8 usb_read8(struct rtw_adapter *padapter, u32 addr)
{
u8 request;
u8 requesttype;
wvalue = (u16)(addr&0x0000ffff);
len = 1;
- usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
+ usbctrl_vendorreq(padapter, request, wvalue, index, &data,
+ len, requesttype);
return data;
}
-static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
+static u16 usb_read16(struct rtw_adapter *padapter, u32 addr)
{
u8 request;
u8 requesttype;
wvalue = (u16)(addr&0x0000ffff);
len = 2;
- usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
+ usbctrl_vendorreq(padapter, request, wvalue, index, &data,
+ len, requesttype);
return data;
}
-static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
+static u32 usb_read32(struct rtw_adapter *padapter, u32 addr)
{
u8 request;
u8 requesttype;
wvalue = (u16)(addr&0x0000ffff);
len = 4;
- usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
+ usbctrl_vendorreq(padapter, request, wvalue, index, &data,
+ len, requesttype);
return data;
}
-static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
+static int usb_write8(struct rtw_adapter *padapter, u32 addr, u8 val)
{
u8 request;
u8 requesttype;
data = val;
- ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
+ ret = usbctrl_vendorreq(padapter, request, wvalue, index, &data,
+ len, requesttype);
return ret;
}
-static int usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
+static int usb_write16(struct rtw_adapter *padapter, u32 addr, u16 val)
{
u8 request;
u8 requesttype;
data = val;
- ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
+ ret = usbctrl_vendorreq(padapter, request, wvalue, index, &data,
+ len, requesttype);
return ret;
}
-static int usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
+static int usb_write32(struct rtw_adapter *padapter, u32 addr, u32 val)
{
u8 request;
u8 requesttype;
len = 4;
data = val;
- ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
+ ret = usbctrl_vendorreq(padapter, request, wvalue, index, &data,
+ len, requesttype);
return ret;
}
-static int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata)
+static int usb_writeN(struct rtw_adapter *padapter,
+ u32 addr, u32 length, u8 *pdata)
{
u8 request;
u8 requesttype;
wvalue = (u16)(addr&0x0000ffff);
len = length;
- memcpy(buf, pdata, len);
+ memcpy(buf, pdata, len);
- ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, buf, len, requesttype);
+ ret = usbctrl_vendorreq(padapter, request, wvalue, index, buf,
+ len, requesttype);
return ret;
}
}
}
-static u32 usb_read_interrupt(struct intf_hdl *pintfhdl, u32 addr)
+static u32 usb_read_interrupt(struct rtw_adapter *adapter, u32 addr)
{
int err;
unsigned int pipe;
u32 ret = _SUCCESS;
- struct rtw_adapter *adapter = pintfhdl->padapter;
struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter);
struct recv_priv *precvpriv = &adapter->recvpriv;
struct usb_device *pusbd = pdvobj->pusbdev;
}
}
-static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
+static u32 usb_read_port(struct rtw_adapter *adapter, u32 addr, u32 cnt,
struct recv_buf *precvbuf)
{
int err;
unsigned long alignment = 0;
u32 ret = _SUCCESS;
struct urb *purb = NULL;
- struct rtw_adapter *adapter = pintfhdl->padapter;
struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter);
struct recv_priv *precvpriv = &adapter->recvpriv;
struct usb_device *pusbd = pdvobj->pusbdev;
}
}
-void rtl8723au_set_intf_ops(struct _io_ops *pops)
+void rtl8723au_set_intf_ops(struct rtw_adapter *padapter)
{
+ struct _io_ops *pops = &padapter->io_ops;
memset((u8 *)pops, 0, sizeof(struct _io_ops));
+++ /dev/null
-/******************************************************************************
- *
- * 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 __CMD_OSDEP_H_
-#define __CMD_OSDEP_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-int _rtw_init_evt_priv23a(struct evt_priv *pevtpriv);
-void _rtw_free_evt_priv23a(struct evt_priv *pevtpriv);
-void _rtw_free_cmd_priv23a(struct cmd_priv *pcmdpriv);
-int _rtw_enqueue_cmd23a(struct rtw_queue *queue, struct cmd_obj *obj);
-
-#endif
#include <rtw_event.h>
#include <rtw_led.h>
#include <rtw_mlme_ext.h>
-#include <rtw_p2p.h>
#include <rtw_ap.h>
#include "ioctl_cfg80211.h"
-#define SPEC_DEV_ID_NONE BIT(0)
-#define SPEC_DEV_ID_DISABLE_HT BIT(1)
-#define SPEC_DEV_ID_ENABLE_PS BIT(2)
-#define SPEC_DEV_ID_RF_CONFIG_1T1R BIT(3)
-#define SPEC_DEV_ID_RF_CONFIG_2T2R BIT(4)
-#define SPEC_DEV_ID_ASSIGN_IFNAME BIT(5)
-
-struct specific_device_id {
- u32 flags;
-
- u16 idVendor;
- u16 idProduct;
-
-};
-
struct registry_priv {
u8 chip_version;
u8 rfintfs;
int RtOutPipe[3];
u8 Queue2Pipe[HW_QUEUE_ENTRY];/* for out pipe mapping */
- u8 irq_alloc;
-
/*-------- below is for USB INTERFACE --------*/
u8 nr_endpoint;
u8 RtNumOutPipes;
int ep_num[5]; /* endpoint number */
- int RegUsbSS;
-
struct semaphore usb_suspend_sema;
struct mutex usb_vendor_req_mutex;
struct mlme_ext_priv mlmeextpriv;
struct cmd_priv cmdpriv;
struct evt_priv evtpriv;
- /* struct io_queue *pio_queue; */
- struct io_priv iopriv;
+ struct _io_ops io_ops;
struct xmit_priv xmitpriv;
struct recv_priv recvpriv;
struct sta_priv stapriv;
struct hostapd_priv *phostapdpriv;
#endif
- struct cfg80211_wifidirect_info cfg80211_wdinfo;
u32 setband;
- struct wifidirect_info wdinfo;
-
-#ifdef CONFIG_8723AU_P2P
- struct wifi_display_info wfd_info;
-#endif /* CONFIG_8723AU_P2P */
void *HalData;
u32 hal_data_sz;
u8 init_adpt_in_progress;
u8 bHaltInProgress;
- void *cmdThread;
- void *evtThread;
- void *xmitThread;
- void *recvThread;
-
void (*intf_start)(struct rtw_adapter *adapter);
void (*intf_stop)(struct rtw_adapter *adapter);
struct net_device *pnetdev;
/* 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;
- struct proc_dir_entry *dir_dev;/* for proc directory */
struct wireless_dev *rtw_wdev;
int net_closed;
u8 bBTFWReady;
u8 bReadPortCancel;
u8 bWritePortCancel;
- u8 bRxRSSIDisplay;
/* The driver will show the desired chan nor when this flag is 1. */
u8 bNotifyChannelChange;
-#ifdef CONFIG_8723AU_P2P
- /* driver will show current P2P status when the application reads it*/
- u8 bShowGetP2PState;
-#endif
struct rtw_adapter *pbuddy_adapter;
/* extend to support multi interface */
/* IFACE_ID0 is equals to PRIMARY_ADAPTER */
/* IFACE_ID1 is equals to SECONDARY_ADAPTER */
u8 iface_id;
-
-#ifdef CONFIG_BR_EXT
- _lock br_ext_lock;
- /* unsigned int macclone_completed; */
- struct nat25_network_db_entry *nethash[NAT25_HASH_SIZE];
- int pppoe_connection_in_progress;
- unsigned char pppoe_addr[MACADDRLEN];
- unsigned char scdb_mac[MACADDRLEN];
- unsigned char scdb_ip[4];
- struct nat25_network_db_entry *scdb_entry;
- unsigned char br_mac[MACADDRLEN];
- unsigned char br_ip[4];
-
- struct br_ext_info ethBrExtInfo;
-#endif /* CONFIG_BR_EXT */
-
- u8 fix_rate;
-
- unsigned char in_cta_test;
-
};
#define adapter_to_dvobj(adapter) (adapter->dvobj)
+++ /dev/null
-/******************************************************************************
- *
- * 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 */
-#ifndef __INC_ETHERNET_H
-#define __INC_ETHERNET_H
-
-#define LLC_HEADER_SIZE 6 /* LLC Header Length */
-
-#endif /* #ifndef __INC_ETHERNET_H */
bool
Hal_MappingOutPipe23a(struct rtw_adapter *pAdapter, u8 NumOutPipe);
-void hal_init_macaddr23a(struct rtw_adapter *adapter);
-
void c2h_evt_clear23a(struct rtw_adapter *adapter);
s32 c2h_evt_read23a(struct rtw_adapter *adapter, u8 *buf);
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_invalid_all(struct rtw_adapter *padapter);
-void rtl8723a_cam_write(struct rtw_adapter *padapter, u32 val1, u32 val2);
+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);
-void rtl8723a_set_tx_pause(struct rtw_adapter *padapter, u8 pause);
+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_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, u8 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__ */
MAX_CHIP_TYPE
};
-enum HW_VARIABLES {
- HW_VAR_MEDIA_STATUS,
- HW_VAR_MEDIA_STATUS1,
- HW_VAR_SET_OPMODE,
- HW_VAR_MAC_ADDR,
- HW_VAR_BSSID,
- HW_VAR_INIT_RTS_RATE,
- HW_VAR_BASIC_RATE,
- HW_VAR_TXPAUSE,
- HW_VAR_BCN_FUNC,
- HW_VAR_CORRECT_TSF,
- HW_VAR_CHECK_BSSID,
- HW_VAR_MLME_DISCONNECT,
- HW_VAR_MLME_SITESURVEY,
- HW_VAR_MLME_JOIN,
- HW_VAR_ON_RCR_AM,
- HW_VAR_OFF_RCR_AM,
- HW_VAR_BEACON_INTERVAL,
- HW_VAR_SLOT_TIME,
- HW_VAR_RESP_SIFS,
- HW_VAR_ACK_PREAMBLE,
- 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,
- HW_VAR_CAM_EMPTY_ENTRY,
- HW_VAR_CAM_INVALID_ALL,
- HW_VAR_CAM_WRITE,
- HW_VAR_CAM_READ,
- HW_VAR_AC_PARAM_VO,
- HW_VAR_AC_PARAM_VI,
- HW_VAR_AC_PARAM_BE,
- HW_VAR_AC_PARAM_BK,
- HW_VAR_ACM_CTRL,
- HW_VAR_AMPDU_MIN_SPACE,
- HW_VAR_AMPDU_FACTOR,
- HW_VAR_RXDMA_AGG_PG_TH,
- HW_VAR_SET_RPWM,
- HW_VAR_H2C_FW_PWRMODE,
- HW_VAR_H2C_FW_JOINBSSRPT,
- HW_VAR_FWLPS_RF_ON,
- HW_VAR_H2C_FW_P2P_PS_OFFLOAD,
- HW_VAR_TDLS_WRCR,
- HW_VAR_TDLS_INIT_CH_SEN,
- HW_VAR_TDLS_RS_RCR,
- HW_VAR_TDLS_DONE_CH_SEN,
- HW_VAR_INITIAL_GAIN,
- HW_VAR_TRIGGER_GPIO_0,
- HW_VAR_BT_SET_COEXIST,
- HW_VAR_BT_ISSUE_DELBA,
- HW_VAR_CURRENT_ANTENNA,
- HW_VAR_ANTENNA_DIVERSITY_LINK,
- HW_VAR_ANTENNA_DIVERSITY_SELECT,
- HW_VAR_SWITCH_EPHY_WoWLAN,
- HW_VAR_EFUSE_BYTES,
- HW_VAR_EFUSE_BT_BYTES,
- HW_VAR_FIFO_CLEARN_UP,
- HW_VAR_CHECK_TXBUF,
- HW_VAR_APFM_ON_MAC, /* Auto FSM to Turn On, include clock, isolation, power control for MAC only */
- /* The valid upper nav range for the HW updating, if the true value is larger than the upper range, the HW won't update it. */
- /* Unit in microsecond. 0 means disable this function. */
- HW_VAR_NAV_UPPER,
- HW_VAR_RPT_TIMER_SETTING,
- HW_VAR_TX_RPT_MAX_MACID,
- HW_VAR_H2C_MEDIA_STATUS_RPT,
- HW_VAR_CHK_HI_QUEUE_EMPTY,
- HW_VAR_READ_LLT_TAB,
-};
-
enum hal_def_variable {
HAL_DEF_UNDERCORATEDSMOOTHEDPWDB,
HAL_DEF_IS_SUPPORT_ANT_DIV,
HAL_ODM_WIFI_DISPLAY_STATE,
};
-enum hal_intf_ps_func {
- HAL_USB_SELECT_SUSPEND,
- HAL_MAX_ID,
-};
-
struct hal_ops {
u32 (*hal_power_on)(struct rtw_adapter *padapter);
u32 (*hal_init)(struct rtw_adapter *padapter);
void (*hal_dm_watchdog)(struct rtw_adapter *padapter);
- void (*SetHwRegHandler)(struct rtw_adapter *padapter,
- u8 variable, u8 *val);
- void (*GetHwRegHandler)(struct rtw_adapter *padapter,
- u8 variable, u8 *val);
-
u8 (*GetHalDefVarHandler)(struct rtw_adapter *padapter,
enum hal_def_variable eVariable,
void *pValue);
void (*Add_RateATid)(struct rtw_adapter *padapter, u32 bitmap,
u8 arg, u8 rssi_level);
- void (*run_thread)(struct rtw_adapter *padapter);
- void (*cancel_thread)(struct rtw_adapter *padapter);
-
- u8 (*interface_ps_func)(struct rtw_adapter *padapter,
- enum hal_intf_ps_func efunc_id, u8 *val);
s32 (*hal_xmit)(struct rtw_adapter *padapter,
struct xmit_frame *pxmitframe);
s32 (*hal_xmitframe_enqueue)(struct rtw_adapter *padapter,
struct xmit_frame *pxmitframe);
- u32 (*read_bbreg)(struct rtw_adapter *padapter, u32 RegAddr,
- u32 BitMask);
- void (*write_bbreg)(struct rtw_adapter *padapter, u32 RegAddr,
- u32 BitMask, u32 Data);
u32 (*read_rfreg)(struct rtw_adapter *padapter, u32 eRFPath,
u32 RegAddr, u32 BitMask);
void (*write_rfreg)(struct rtw_adapter *padapter, u32 eRFPath,
};
#define GET_EEPROM_EFUSE_PRIV(adapter) (&adapter->eeprompriv)
-#define is_boot_from_eeprom(adapter) (adapter->eeprompriv.EepromOrEfuse)
-
-extern int rtw_ht_enable23A;
-extern int rtw_cbw40_enable23A;
-extern int rtw_ampdu_enable23A;/* for enable tx_ampdu */
void rtw_hal_def_value_init23a(struct rtw_adapter *padapter);
int pm_netdev_open23a(struct net_device *pnetdev, u8 bnormal);
uint rtw_hal_init23a(struct rtw_adapter *padapter);
uint rtw_hal_deinit23a(struct rtw_adapter *padapter);
void rtw_hal_stop(struct rtw_adapter *padapter);
-void rtw_hal_set_hwreg23a(struct rtw_adapter *padapter, u8 variable, u8 *val);
-void rtw23a_hal_get_hwreg(struct rtw_adapter *padapter, u8 variable, u8 *val);
void rtw_hal_chip_configure23a(struct rtw_adapter *padapter);
void rtw_hal_read_chip_info23a(struct rtw_adapter *padapter);
u32 rtw_hal_inirp_init23a(struct rtw_adapter *padapter);
u32 rtw_hal_inirp_deinit23a(struct rtw_adapter *padapter);
-u8 rtw_hal_intf_ps_func23a(struct rtw_adapter *padapter,
- enum hal_intf_ps_func efunc_id, u8 *val);
-
s32 rtw_hal_xmit23aframe_enqueue(struct rtw_adapter *padapter,
struct xmit_frame *pxmitframe);
s32 rtw_hal_xmit23a(struct rtw_adapter *padapter,
void rtw_hal_update_ra_mask23a(struct sta_info *psta, u8 rssi_level);
void rtw_hal_add_ra_tid23a(struct rtw_adapter *padapter, u32 bitmap, u8 arg, u8 rssi_level);
void rtw_hal_clone_data(struct rtw_adapter *dst_padapter, struct rtw_adapter *src_padapter);
-void rtw_hal_start_thread23a(struct rtw_adapter *padapter);
-void rtw_hal_stop_thread23a(struct rtw_adapter *padapter);
void rtw_hal_bcn_related_reg_setting23a(struct rtw_adapter *padapter);
-u32 rtw_hal_read_bbreg23a(struct rtw_adapter *padapter, u32 RegAddr, u32 BitMask);
-void rtw_hal_write_bbreg23a(struct rtw_adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data);
u32 rtw_hal_read_rfreg23a(struct rtw_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask);
void rtw_hal_write_rfreg23a(struct rtw_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask, u32 Data);
s32 rtw_hal_c2h_handler23a(struct rtw_adapter *adapter, struct c2h_evt_hdr *c2h_evt);
c2h_id_filter rtw_hal_c2h_id_filter_ccx23a(struct rtw_adapter *adapter);
+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);
#endif /* __HAL_INTF_H__ */
#define WEP_KEY_LEN 13
-
-/*
-
- 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;
-};
-
-struct ieee80211_info_element_hdr {
- u8 id;
- u8 len;
-} __attribute__ ((packed));
-
-struct ieee80211_info_element {
- u8 id;
- u8 len;
- u8 data[0];
-} __attribute__ ((packed));
-
-
-struct ieee80211_txb {
- u8 nr_frags;
- u8 encrypted;
- u16 reserved;
- u16 frag_size;
- u16 payload_size;
- struct sk_buff *fragments[0];
-};
-
-
/* 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
#define IEEE_G (1<<2)
#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
-/* Baron move to ieee80211.c */
-int ieee80211_is_empty_essid23a(const char *essid, int essid_len);
-
enum _PUBLIC_ACTION{
ACT_PUBLIC_BSSCOEXIST = 0, /* 20/40 BSS Coexistence */
ACT_PUBLIC_DSE_ENABLE = 1,
/*, (channel)->orig_mag*/ \
/*, (channel)->orig_mpwr*/ \
-/* Parsed Information Elements */
-struct rtw_ieee802_11_elems {
- u8 *ssid;
- u8 ssid_len;
- u8 *supp_rates;
- u8 supp_rates_len;
- u8 *fh_params;
- u8 fh_params_len;
- u8 *ds_params;
- u8 ds_params_len;
- u8 *cf_params;
- u8 cf_params_len;
- u8 *tim;
- u8 tim_len;
- u8 *ibss_params;
- u8 ibss_params_len;
- u8 *challenge;
- u8 challenge_len;
- u8 *erp_info;
- u8 erp_info_len;
- u8 *ext_supp_rates;
- u8 ext_supp_rates_len;
- u8 *wpa_ie;
- u8 wpa_ie_len;
- u8 *rsn_ie;
- u8 rsn_ie_len;
- u8 *wme;
- u8 wme_len;
- u8 *wme_tspec;
- u8 wme_tspec_len;
- u8 *wps_ie;
- u8 wps_ie_len;
- u8 *power_cap;
- u8 power_cap_len;
- u8 *supp_channels;
- u8 supp_channels_len;
- u8 *mdie;
- u8 mdie_len;
- u8 *ftie;
- u8 ftie_len;
- u8 *timeout_int;
- u8 timeout_int_len;
- u8 *ht_capabilities;
- u8 ht_capabilities_len;
- u8 *ht_operation;
- u8 ht_operation_len;
- u8 *vendor_ht_cap;
- u8 vendor_ht_cap_len;
-};
-
-enum parse_res {
- ParseOK = 0,
- ParseUnknown = 1,
- ParseFailed = -1
-};
-
-enum parse_res rtw_ieee802_11_parse_elems23a(u8 *start, uint len,
- struct rtw_ieee802_11_elems *elems,
- int show_errors);
-
u8 *rtw_set_fixed_ie23a(unsigned char *pbuf, unsigned int len, unsigned char *source, unsigned int *frlen);
-u8 *rtw_set_ie23a(u8 *pbuf, int index, uint len, u8 *source, uint *frlen);
+u8 *rtw_set_ie23a(u8 *pbuf, int index, uint len, const u8 *source, uint *frlen);
enum secondary_ch_offset {
SCN = 0, /* no secondary channel */
void rtw_set_supported_rate23a(u8* SupportedRates, uint mode) ;
-unsigned char *rtw_get_wpa_ie23a(unsigned char *pie, int *wpa_ie_len, int limit);
-unsigned char *rtw_get_wpa2_ie23a(unsigned char *pie, int *rsn_ie_len, int limit);
-int rtw_get_wpa_cipher_suite23a(u8 *s);
-int rtw_get_wpa2_cipher_suite23a(u8 *s);
-int rtw_parse_wpa_ie23a(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x);
-int rtw_parse_wpa2_ie23a(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x);
+int rtw_get_wpa_cipher_suite23a(const u8 *s);
+int rtw_get_wpa2_cipher_suite23a(const u8 *s);
+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);
int rtw_get_sec_ie23a(u8 *in_ie,uint in_len,u8 *rsn_ie,u16 *rsn_len,u8 *wpa_ie,u16 *wpa_len);
u8 *rtw_get_wps_attr23a(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_attr, u32 *len_attr);
u8 *rtw_get_wps_attr_content23a(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_ies23a(u8 *buf, u32 buf_len);
-void dump_wps_ie23a(u8 *ie, u32 ie_len);
-
-#ifdef CONFIG_8723AU_P2P
-void dump_p2p_ie23a(u8 *ie, u32 ie_len);
-u8 *rtw_get_p2p_ie23a(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen);
-u8 *rtw_get_p2p_attr23a(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_attr, u32 *len_attr);
-u8 *rtw_get_p2p_attr23a_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_content, uint *len_content);
-u32 rtw_set_p2p_attr_content23a(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr);
-void rtw_wlan_bssid_ex_remove_p2p_attr23a(struct wlan_bssid_ex *bss_ex, u8 attr_id);
-#endif
-
-#ifdef CONFIG_8723AU_P2P
-int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen);
-int rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id ,u8 *attr_content, uint *attr_contentlen);
-#endif /* CONFIG_8723AU_P2P */
-
uint rtw_get_rateset_len23a(u8 *rateset);
struct registry_priv;
#include <drv_types.h>
void rtw_os_indicate_disconnect23a(struct rtw_adapter *adapter);
-void rtw_os_indicate_connect23a(struct rtw_adapter *adapter);
-void rtw_os_indicate_scan_done23a(struct rtw_adapter *padapter, bool aborted);
-void rtw_report_sec_ie23a(struct rtw_adapter *adapter, u8 authmode, u8 *sec_ie);
-
void rtw_reset_securitypriv23a(struct rtw_adapter *adapter);
#endif /* _MLME_OSDEP_H_ */
u8 rtw_free_drv_sw23a(struct rtw_adapter *padapter);
u8 rtw_reset_drv_sw23a(struct rtw_adapter *padapter);
-u32 rtw_start_drv_threads23a(struct rtw_adapter *padapter);
-void rtw_stop_drv_threads23a (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);
#include <linux/kref.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
-#include <linux/circ_buf.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
#include <asm/atomic.h>
#include <linux/sched.h>
#include <linux/etherdevice.h>
#include <linux/wireless.h>
-#include <net/iw_handler.h>
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
#include <linux/delay.h>
extern unsigned char REALTEK_96B_IE23A[];
extern unsigned char MCS_rate_2R23A[16];
-extern unsigned char RTW_WPA_OUI23A[];
extern unsigned char WPA_TKIP_CIPHER23A[4];
extern unsigned char RSN_TKIP_CIPHER23A[4];
void _rtw_init_queue23a(struct rtw_queue *pqueue);
u32 _rtw_queue_empty23a(struct rtw_queue *pqueue);
-static inline u32 bitshift(u32 bitmask)
-{
- u32 i;
-
- for (i = 0; i <= 31; i++)
- if (((bitmask>>i) & 0x1) == 1) break;
-
- return i;
-}
-
void rtw_suspend_lock_init(void);
void rtw_suspend_lock_uninit(void);
void rtw_lock_suspend(void);
#define FUNC_ADPT_FMT "%s(%s)"
#define FUNC_ADPT_ARG(adapter) __func__, adapter->pnetdev->name
-#define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)),(sig), 1)
-
-u64 rtw_modular6423a(u64 x, u64 y);
-u64 rtw_division6423a(u64 x, u64 y);
-
-
/* Macros for handling unaligned memory accesses */
#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
void *rtw_cbuf_pop23a(struct rtw_cbuf *cbuf);
struct rtw_cbuf *rtw_cbuf_alloc23a(u32 size);
void rtw_cbuf_free(struct rtw_cbuf *cbuf);
-int rtw_change_ifname(struct rtw_adapter *padapter, const char *ifname);
s32 c2h_evt_hdl(struct rtw_adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter);
-void indicate_wx_scan_complete_event(struct rtw_adapter *padapter);
u8 rtw_do_join23a(struct rtw_adapter *padapter);
#endif
int rtw_recv_entry23a(struct recv_frame *precv_frame);
int rtw_recv_indicatepkt23a(struct rtw_adapter *adapter, struct recv_frame *precv_frame);
-void rtw_recv_returnpacket(struct net_device *cnxt, struct sk_buff *preturnedpkt);
-void rtw_hostapd_mlme_rx23a(struct rtw_adapter *padapter, 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);
-int rtw_os_recv_resource_alloc23a(struct rtw_adapter *padapter, struct recv_frame *precvframe);
-void rtw_os_recv_resource_free(struct recv_priv *precvpriv);
-
-int rtw_os_recvbuf_resource_alloc23a(struct rtw_adapter *padapter, struct recv_buf *precvbuf);
-int rtw_os_recvbuf_resource_free23a(struct rtw_adapter *padapter, struct recv_buf *precvbuf);
-
-void rtw_os_read_port23a(struct rtw_adapter *padapter, struct recv_buf *precvbuf);
void rtw_init_recv_timer23a(struct recv_reorder_ctrl *preorder_ctrl);
u8 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);
-#ifdef CONFIG_8723AU_P2P
-void rtl8723a_set_p2p_ps_offload_cmd(struct rtw_adapter * padapter, u8 p2p_ps_state);
-#endif /* CONFIG_8723AU_P2P */
-
void CheckFwRsvdPageContent23a(struct rtw_adapter *padapter);
#endif
bool bMACFuncEnable;
-#ifdef CONFIG_8723AU_P2P
- struct P2P_PS_Offload_t p2p_ps_offload;
-#endif
-
-
/* */
/* For USB Interface HAL related */
/* */
/* Interrupt related register information. */
u32 IntArray[2];
u32 IntrMask[2];
-
- /* */
- /* For SDIO Interface HAL related */
- /* */
-
- /* Auto FSM to Turn On, include clock, isolation, power control for MAC only */
- u8 bMacPwrCtrlOn;
-
};
#define GET_HAL_DATA(__pAdapter) ((struct hal_data_8723a *)((__pAdapter)->HalData))
void Hal_InitChannelPlan23a(struct rtw_adapter *padapter);
void rtl8723a_set_hal_ops(struct hal_ops *pHalFunc);
-void SetHwReg8723A(struct rtw_adapter *padapter, u8 variable, u8 *val);
-void GetHwReg8723A(struct rtw_adapter *padapter, u8 variable, u8 *val);
#ifdef CONFIG_8723AU_BT_COEXIST
void rtl8723a_SingleDualAntennaDetection(struct rtw_adapter *padapter);
#endif
#ifdef CONFIG_8723AU_AP_MODE
/* external function */
-void rtw_indicate_sta_assoc_event23a(struct rtw_adapter *padapter, struct sta_info *psta);
-void rtw_indicate_sta_disassoc_event23a(struct rtw_adapter *padapter, struct sta_info *psta);
void init_mlme_ap_info23a(struct rtw_adapter *padapter);
void free_mlme_ap_info23a(struct rtw_adapter *padapter);
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, u8 *pbuf, int len);
+int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf, unsigned int len);
void rtw_ap_restore_network(struct rtw_adapter *padapter);
void rtw_set_macaddr_acl23a(struct rtw_adapter *padapter, int mode);
int rtw_acl_add_sta23a(struct rtw_adapter *padapter, u8 *addr);
#include <ieee80211.h> /* <ieee80211/ieee80211.h> */
-#define FREE_CMDOBJ_SZ 128
-
#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;
u8 res;
u32 cmdsz;
u8 *rsp;
u32 rspsz;
- /* struct semaphore cmd_sem; */
- struct list_head list;
};
struct cmd_priv {
- struct semaphore cmd_queue_sema;
- /* struct semaphore cmd_done_sema; */
- struct semaphore terminate_cmdthread_sema;
- struct rtw_queue cmd_queue;
- u8 cmd_seq;
+ struct workqueue_struct *wq;
u8 *cmd_buf; /* shall be non-paged, and 4 bytes aligned */
u8 *cmd_allocated_buf;
u8 *rsp_buf; /* shall be non-paged, and 4 bytes aligned */
u32 cmd_issued_cnt;
u32 cmd_done_cnt;
u32 rsp_cnt;
- u8 cmdthd_running;
struct rtw_adapter *padapter;
};
#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \
do {\
- INIT_LIST_HEAD(&pcmd->list);\
pcmd->cmdcode = code;\
pcmd->parmbuf = (u8 *)(pparm);\
pcmd->cmdsz = sizeof (*pparm);\
#define c2h_evt_exist(c2h_evt) ((c2h_evt)->id || (c2h_evt)->plen)
-u32 rtw_enqueue_cmd23a(struct cmd_priv *pcmdpriv, struct cmd_obj *obj);
+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);
void rtw_free_evt_priv23a (struct evt_priv *pevtpriv);
void rtw_cmd_clr_isr23a(struct cmd_priv *pcmdpriv);
void rtw_evt_notify_isr(struct evt_priv *pevtpriv);
-#ifdef CONFIG_8723AU_P2P
-u8 p2p_protocol_wk_cmd23a(struct rtw_adapter*padapter, int intCmdType );
-#endif /* CONFIG_8723AU_P2P */
enum rtw_drvextra_cmd_id
{
u8 rtw_c2h_wk_cmd23a(struct rtw_adapter *padapter, u8 *c2h_evt);
-u8 rtw_drvextra_cmd_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf);
+u8 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);
#define _INTF_ASYNC_ BIT(0) /* support async io */
struct intf_priv;
-struct intf_hdl;
-struct io_queue;
struct _io_ops
{
- u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
- u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
- u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+ u8 (*_read8)(struct rtw_adapter *adapter, u32 addr);
+ u16 (*_read16)(struct rtw_adapter *adapter, u32 addr);
+ u32 (*_read32)(struct rtw_adapter *adapter, u32 addr);
- int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
- int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
- int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
- int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata);
+ int (*_write8)(struct rtw_adapter *adapter, u32 addr, u8 val);
+ int (*_write16)(struct rtw_adapter *adapter, u32 addr, u16 val);
+ int (*_write32)(struct rtw_adapter *adapter, u32 addr, u32 val);
+ int (*_writeN)(struct rtw_adapter *adapter, u32 addr, u32 length, u8 *pdata);
- int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
- int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
- int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
+ void (*_read_mem)(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
+ void (*_write_mem)(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
- void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
- void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
+ u32 (*_read_interrupt)(struct rtw_adapter *adapter, u32 addr);
- void (*_sync_irp_protocol_rw)(struct io_queue *pio_q);
-
- u32 (*_read_interrupt)(struct intf_hdl *pintfhdl, u32 addr);
-
- u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, struct recv_buf *rbuf);
- u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, struct xmit_buf *pmem);
-
- u32 (*_write_scsi)(struct intf_hdl *pintfhdl,u32 cnt, u8 *pmem);
-
- void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
- void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
+ u32 (*_read_port)(struct rtw_adapter *adapter, u32 addr, u32 cnt, struct recv_buf *rbuf);
+ u32 (*_write_port)(struct rtw_adapter *adapter, u32 addr, u32 cnt, struct xmit_buf *pmem);
+ void (*_read_port_cancel)(struct rtw_adapter *adapter);
+ void (*_write_port_cancel)(struct rtw_adapter *adapter);
};
struct io_req {
u8 *cnxt;
};
-struct intf_hdl {
- struct rtw_adapter *padapter;
- struct dvobj_priv *pintf_dev;/* pointer to &(padapter->dvobjpriv); */
-
- struct _io_ops io_ops;
-
-};
-
struct reg_protocol_rd {
#ifdef __LITTLE_ENDIAN
};
-
-/*
-Below is the data structure used by _io_handler
-
-*/
-
-struct io_queue {
- spinlock_t lock;
- struct list_head free_ioreqs;
- struct list_head pending; /* The io_req list that will be served in the single protocol read/write. */
- struct list_head processing;
- u8 *free_ioreqs_buf; /* 4-byte aligned */
- u8 *pallocated_free_ioreqs_buf;
- struct intf_hdl intf;
-};
-
-struct io_priv{
-
- struct rtw_adapter *padapter;
-
- struct intf_hdl intf;
-
-};
-
-uint ioreq_flush(struct rtw_adapter *adapter, struct io_queue *ioqueue);
-void sync_ioreq_enqueue(struct io_req *preq,struct io_queue *ioqueue);
-uint sync_ioreq_flush(struct rtw_adapter *adapter, struct io_queue *ioqueue);
-
-uint free_ioreq(struct io_req *preq, struct io_queue *pio_queue);
-struct io_req *alloc_ioreq(struct io_queue *pio_q);
-
-uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl);
-void unregister_intf_hdl(struct intf_hdl *pintfhdl);
-
void _rtw_attrib_read(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_attrib_write(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
int _rtw_write3223a(struct rtw_adapter *adapter, u32 addr, u32 val);
int _rtw_writeN23a(struct rtw_adapter *adapter, u32 addr, u32 length, u8 *pdata);
-int _rtw_write823a_async23a(struct rtw_adapter *adapter, u32 addr, u8 val);
-int _rtw_write1623a_async(struct rtw_adapter *adapter, u32 addr, u16 val);
-int _rtw_write3223a_async23a(struct rtw_adapter *adapter, u32 addr, u32 val);
-
void _rtw_write_mem23a(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
u32 _rtw_write_port23a(struct rtw_adapter *adapter, u32 addr, u32 cnt, struct xmit_buf *pmem);
-u32 _rtw_write_port23a_and_wait23a(struct rtw_adapter *adapter, u32 addr, u32 cnt, struct xmit_buf *pmem, int timeout_ms);
void _rtw_write_port23a_cancel(struct rtw_adapter *adapter);
#ifdef DBG_IO
#define rtw_write32(adapter, addr, val) dbg_rtw_write3223a((adapter), (addr), (val), __FUNCTION__, __LINE__)
#define rtw_writeN(adapter, addr, length, data) dbg_rtw_writeN23a((adapter), (addr), (length), (data), __FUNCTION__, __LINE__)
-#define rtw_write8_async(adapter, addr, val) _rtw_write823a_async23a((adapter), (addr), (val))
-#define rtw_write16_async(adapter, addr, val) _rtw_write1623a_async((adapter), (addr), (val))
-#define rtw_write32_async(adapter, addr, val) _rtw_write3223a_async23a((adapter), (addr), (val))
-
#define rtw_write_mem(adapter, addr, cnt, mem) _rtw_write_mem23a((adapter), addr, cnt, mem)
#define rtw_write_port(adapter, addr, cnt, mem) _rtw_write_port23a(adapter, addr, cnt, mem)
-#define rtw_write_port_and_wait(adapter, addr, cnt, mem, timeout_ms) _rtw_write_port23a_and_wait23a((adapter), (addr), (cnt), (mem), (timeout_ms))
#define rtw_write_port_cancel(adapter) _rtw_write_port23a_cancel(adapter)
#else /* DBG_IO */
#define rtw_read8(adapter, addr) _rtw_read823a((adapter), (addr))
#define rtw_write32(adapter, addr, val) _rtw_write3223a((adapter), (addr), (val))
#define rtw_writeN(adapter, addr, length, data) _rtw_writeN23a((adapter), (addr), (length), (data))
-#define rtw_write8_async(adapter, addr, val) _rtw_write823a_async23a((adapter), (addr), (val))
-#define rtw_write16_async(adapter, addr, val) _rtw_write1623a_async((adapter), (addr), (val))
-#define rtw_write32_async(adapter, addr, val) _rtw_write3223a_async23a((adapter), (addr), (val))
-
#define rtw_write_mem(adapter, addr, cnt, mem) _rtw_write_mem23a((adapter), (addr), (cnt), (mem))
#define rtw_write_port(adapter, addr, cnt, mem) _rtw_write_port23a((adapter), (addr), (cnt), (mem))
-#define rtw_write_port_and_wait(adapter, addr, cnt, mem, timeout_ms) _rtw_write_port23a_and_wait23a((adapter), (addr), (cnt), (mem), (timeout_ms))
#define rtw_write_port_cancel(adapter) _rtw_write_port23a_cancel((adapter))
#endif /* DBG_IO */
-void rtw_write_scsi(struct rtw_adapter *adapter, u32 cnt, u8 *pmem);
-
-/* ioreq */
-void ioreq_read8(struct rtw_adapter *adapter, u32 addr, u8 *pval);
-void ioreq_read16(struct rtw_adapter *adapter, u32 addr, u16 *pval);
-void ioreq_read32(struct rtw_adapter *adapter, u32 addr, u32 *pval);
-void ioreq_write8(struct rtw_adapter *adapter, u32 addr, u8 val);
-void ioreq_write16(struct rtw_adapter *adapter, u32 addr, u16 val);
-void ioreq_write32(struct rtw_adapter *adapter, u32 addr, u32 val);
-
-int rtw_init_io_priv23a(struct rtw_adapter *padapter, void (*set_intf_ops)(struct _io_ops *pops));
-
-uint alloc_io_queue(struct rtw_adapter *adapter);
-void free_io_queue(struct rtw_adapter *adapter);
-void async_bus_io(struct io_queue *pio_q);
-void bus_sync_io(struct io_queue *pio_q);
-u32 _ioreq2rwmem(struct io_queue *pio_q);
-void dev_power_down(struct rtw_adapter * Adapter, u8 bpwrup);
-
#define PlatformEFIOWrite1Byte(_a,_b,_c) \
rtw_write8(_a,_b,_c)
#define PlatformEFIOWrite2Byte(_a,_b,_c) \
u8 token; /* Used to record the dialog token of p2p invitation request frame. */
};
-#ifdef CONFIG_8723AU_P2P
-
-struct wifi_display_info {
- u16 wfd_enable; /* Enable/Disable the WFD function. */
- u16 rtsp_ctrlport; /* TCP port number at which the this WFD device listens for RTSP messages */
- u16 peer_rtsp_ctrlport; /* TCP port number at which the peer WFD device listens for RTSP messages */
- /* This filed should be filled when receiving the gropu negotiation request */
-
- u8 peer_session_avail; /* WFD session is available or not for the peer wfd device. */
- /* This variable will be set when sending the provisioning discovery request to peer WFD device. */
- /* And this variable will be reset when it is read by using the iwpriv p2p_get wfd_sa command. */
- u8 ip_address[4];
- u8 peer_ip_address[4];
- u8 wfd_pc; /* WFD preferred connection */
- /* 0 -> Prefer to use the P2P for WFD connection on peer side. */
- /* 1 -> Prefer to use the TDLS for WFD connection on peer side. */
-
- u8 wfd_device_type;/* WFD Device Type */
- /* 0 -> WFD Source Device */
- /* 1 -> WFD Primary Sink Device */
- enum SCAN_RESULT_TYPE scan_result_type; /* Used when P2P is enable. This parameter will impact the scan result. */
-};
-#endif /* CONFIG_8723AU_P2P */
-
struct tx_provdisc_req_info {
u16 wps_config_method_request; /* Used when sending the provisioning request frame */
u16 peer_channel_num[2]; /* The channel number which the receiver stands. */
u8 operation_ch[2]; /* Store the operation channel of invitation request frame */
};
-struct cfg80211_wifidirect_info {
- struct timer_list remain_on_ch_timer;
- u8 restore_channel;
- struct ieee80211_channel remain_on_ch_channel;
- enum nl80211_channel_type remain_on_ch_type;
- u64 remain_on_ch_cookie;
- bool is_ro_ch;
-};
-
-struct wifidirect_info {
- struct rtw_adapter *padapter;
- struct timer_list find_phase_timer;
- struct timer_list restore_p2p_state_timer;
-
- /* Used to do the scanning. After confirming the peer is availalble, the driver transmits the P2P frame to peer. */
- struct timer_list pre_tx_scan_timer;
- struct timer_list reset_ch_sitesurvey;
- struct timer_list reset_ch_sitesurvey2; /* Just for resetting the scan limit function by using p2p nego */
- struct tx_provdisc_req_info tx_prov_disc_info;
- struct rx_provdisc_req_info rx_prov_disc_info;
- struct tx_invite_req_info invitereq_info;
- struct profile_info profileinfo[P2P_MAX_PERSISTENT_GROUP_NUM]; /* Store the profile information of persistent group */
- struct tx_invite_resp_info inviteresp_info;
- struct tx_nego_req_info nego_req_info;
- struct group_id_info groupid_info; /* Store the group id information when doing the group negotiation handshake. */
- struct scan_limit_info rx_invitereq_info; /* Used for get the limit scan channel from the Invitation procedure */
- struct scan_limit_info p2p_info; /* Used for get the limit scan channel from the P2P negotiation handshake */
-#ifdef CONFIG_8723AU_P2P
- struct wifi_display_info *wfd_info;
-#endif
- enum P2P_ROLE role;
- enum P2P_STATE pre_p2p_state;
- enum P2P_STATE p2p_state;
- u8 device_addr[ETH_ALEN]; /* The device address should be the mac address of this device. */
- u8 interface_addr[ETH_ALEN];
- u8 social_chan[4];
- u8 listen_channel;
- u8 operating_channel;
- u8 listen_dwell; /* This value should be between 1 and 3 */
- u8 support_rate[8];
- u8 p2p_wildcard_ssid[P2P_WILDCARD_SSID_LEN];
- u8 intent; /* should only include the intent value. */
- u8 p2p_peer_interface_addr[ETH_ALEN];
- u8 p2p_peer_device_addr[ETH_ALEN];
- u8 peer_intent; /* Included the intent value and tie breaker value. */
- u8 device_name[WPS_MAX_DEVICE_NAME_LEN]; /* Device name for displaying on searching device screen */
- u8 device_name_len;
- u8 profileindex; /* Used to point to the index of profileinfo array */
- u8 peer_operating_ch;
- u8 find_phase_state_exchange_cnt;
- u16 device_password_id_for_nego; /* The device password ID for group negotation */
- u8 negotiation_dialog_token;
- /* SSID information for group negotitation */
- u8 nego_ssid[IEEE80211_MAX_SSID_LEN];
- u8 nego_ssidlen;
- u8 p2p_group_ssid[IEEE80211_MAX_SSID_LEN];
- u8 p2p_group_ssid_len;
- u8 persistent_supported; /* Flag to know the persistent function should be supported or not. */
- /* In the Sigma test, the Sigma will provide this enable from the sta_set_p2p CAPI. */
- /* 0: disable */
- /* 1: enable */
- u8 session_available; /* Flag to set the WFD session available to enable or disable "by Sigma" */
- /* In the Sigma test, the Sigma will disable the session available by using the sta_preset CAPI. */
- /* 0: disable */
- /* 1: enable */
-
- u8 wfd_tdls_enable; /* Flag to enable or disable the TDLS by WFD Sigma */
- /* 0: disable */
- /* 1: enable */
- u8 wfd_tdls_weaksec; /* Flag to enable or disable the weak security function for TDLS by WFD Sigma */
- /* 0: disable */
- /* In this case, the driver can't issue the tdsl setup request frame. */
- /* 1: enable */
- /* In this case, the driver can issue the tdls setup request frame */
- /* even the current security is weak security. */
-
- enum P2P_WPSINFO ui_got_wps_info; /* This field will store the WPS value (PIN value or PBC) that UI had got from the user. */
- u16 supported_wps_cm; /* This field describes the WPS config method which this driver supported. */
- /* The value should be the combination of config method defined in page104 of WPS v2.0 spec. */
- uint channel_list_attr_len; /* This field will contain the length of body of P2P Channel List attribute of group negotitation response frame. */
- u8 channel_list_attr[100]; /* This field will contain the body of P2P Channel List attribute of group negotitation response frame. */
- /* We will use the channel_cnt and channel_list fields when constructing the group negotitation confirm frame. */
-#ifdef CONFIG_8723AU_P2P
- enum P2P_PS_MODE p2p_ps_mode; /* indicate p2p ps mode */
- enum P2P_PS_STATE p2p_ps_state; /* indicate p2p ps state */
- u8 noa_index; /* Identifies and instance of Notice of Absence timing. */
- u8 ctwindow; /* Client traffic window. A period of time in TU after TBTT. */
- u8 opp_ps; /* opportunistic power save. */
- u8 noa_num; /* number of NoA descriptor in P2P IE. */
- u8 noa_count[P2P_MAX_NOA_NUM]; /* Count for owner, Type of client. */
- u32 noa_duration[P2P_MAX_NOA_NUM]; /* Max duration for owner, preferred or min acceptable duration for client. */
- u32 noa_interval[P2P_MAX_NOA_NUM]; /* Length of interval for owner, preferred or max acceptable interval of client. */
- u32 noa_start_time[P2P_MAX_NOA_NUM]; /* schedule expressed in terms of the lower 4 bytes of the TSF timer. */
-#endif /* CONFIG_8723AU_P2P */
-};
-
struct tdls_ss_record { /* signal strength record */
u8 macaddr[ETH_ALEN];
u8 RxPWDBAll;
u8 watchdog_count;
u8 dev_discovered; /* WFD_TDLS: for sigma test */
u8 enable;
-#ifdef CONFIG_8723AU_P2P
- struct wifi_display_info *wfd_info;
-#endif
};
struct mlme_priv {
int event_thread(void *context);
void rtw23a_join_to_handler(unsigned long);
-void rtw_free_network_queue23a(struct rtw_adapter *adapter, u8 isfreeall);
+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 lock_scanned_queue);
void rtw_indicate_disconnect23a(struct rtw_adapter *adapter);
void rtw_indicate_connect23a(struct rtw_adapter *adapter);
-void rtw_indicate_scan_done23a(struct rtw_adapter *padapter, bool aborted);
void rtw_scan_abort23a(struct rtw_adapter *adapter);
int rtw_restruct_sec_ie23a(struct rtw_adapter *adapter, u8 *in_ie, u8 *out_ie,
void rtw_set_scan_deny_timer_hdl(unsigned long data);
void rtw_set_scan_deny(struct rtw_adapter *adapter, u32 ms);
-int _rtw_init_mlme_priv23a(struct rtw_adapter *padapter);
-
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);
-void _rtw_free_network23a(struct mlme_priv *pmlmepriv,
- struct wlan_network *pnetwork, u8 isfreeall);
-void _rtw_free_network23a_nolock23a(struct mlme_priv *pmlmepriv,
- struct wlan_network *pnetwork);
-
-struct wlan_network *_rtw_find_network23a(struct rtw_queue *scanned_queue, u8 *addr);
-
-void _rtw_free_network23a_queue23a(struct rtw_adapter *padapter, u8 isfreeall);
-
int rtw_if_up23a(struct rtw_adapter *padapter);
int rtw_linked_check(struct rtw_adapter *padapter);
-u8 *rtw_get_capability23a_from_ie(u8 *ie);
-u8 *rtw_get_timestampe_from_ie23a(u8 *ie);
-u8 *rtw_get_beacon_interval23a_from_ie(u8 *ie);
+__le16 *rtw_get_capability23a_from_ie(u8 *ie);
+__le16 *rtw_get_beacon_interval23a_from_ie(u8 *ie);
void rtw_joinbss_reset23a(struct rtw_adapter *padapter);
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 rtw23a_roaming(struct rtw_adapter *adapter,
struct wlan_network *tgt_network);
void rtw_set_roaming(struct rtw_adapter *adapter, u8 to_roaming);
-u8 rtw_to_roaming(struct rtw_adapter *adapter);
-void rtw_stassoc_hw_rpt23a(struct rtw_adapter *adapter, struct sta_info *psta);
#endif /* __RTL871X_MLME_H_ */
#define _54M_RATE_ 11
-extern unsigned char RTW_WPA_OUI23A[];
extern unsigned char WMM_OUI23A[];
extern unsigned char WPS_OUI23A[];
extern unsigned char WFD_OUI23A[];
struct mlme_handler {
char *str;
- unsigned int (*func)(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
+ int (*func)(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
};
struct action_handler {
unsigned int num;
char* str;
- unsigned int (*func)(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
+ int (*func)(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
};
struct ss_res
void UpdateBrateTbl23a(struct rtw_adapter *padapter,u8 *mBratesOS);
void Update23aTblForSoftAP(u8 *bssrateset, u32 bssratelen);
-void Save_DM_Func_Flag23a(struct rtw_adapter *padapter);
-void Restore_DM_Func_Flag23a(struct rtw_adapter *padapter);
-void Switch_DM_Func23a(struct rtw_adapter *padapter, unsigned long mode, u8 enable);
-
void Set_MSR23a(struct rtw_adapter *padapter, u8 type);
u8 rtw_get_oper_ch23a(struct rtw_adapter *adapter);
unsigned int decide_wait_for_beacon_timeout23a(unsigned int bcn_interval);
-void write_cam23a(struct rtw_adapter *padapter, u8 entry, u16 ctrl,
- u8 *mac, u8 *key);
void clear_cam_entry23a(struct rtw_adapter *padapter, u8 entry);
void invalidate_cam_all23a(struct rtw_adapter *padapter);
-void CAM_empty_entry23a(struct rtw_adapter *Adapter, u8 ucIndex);
int allocate_fw_sta_entry23a(struct rtw_adapter *padapter);
void flush_all_cam_entry23a(struct rtw_adapter *padapter);
int WMM_param_handler23a(struct rtw_adapter *padapter,
struct ndis_802_11_var_ies *pIE);
-#ifdef CONFIG_8723AU_P2P
-int WFD_info_handler(struct rtw_adapter *padapter,
- struct ndis_802_11_var_ies *pIE);
-#endif
void WMMOnAssocRsp23a(struct rtw_adapter *padapter);
void HT_caps_handler23a(struct rtw_adapter *padapter,
void update_beacon23a_info(struct rtw_adapter *padapter, u8 *pframe, uint len,
struct sta_info *psta);
-int rtw_check_bcn_info23a(struct rtw_adapter *Adapter, u8 *pframe, u32 packet_len);
+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);
s32 dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter *padapter,
struct xmit_frame *pmgntframe);
-#ifdef CONFIG_8723AU_P2P
-void issue_probersp23a_p2p23a(struct rtw_adapter *padapter, unsigned char *da);
-void issue_p2p_provision_request23a(struct rtw_adapter *padapter, u8 *pssid,
- u8 ussidlen, u8* pdev_raddr);
-void issue_p2p_GO_request23a(struct rtw_adapter *padapter, u8* raddr);
-void issue23a_probereq_p2p(struct rtw_adapter *padapter, u8 *da);
-int issue23a_probereq_p2p_ex(struct rtw_adapter *adapter, u8 *da, int try_cnt,
- int wait_ms);
-void issue_p2p_invitation_response23a(struct rtw_adapter *padapter, u8* raddr,
- u8 dialogToken, u8 success);
-void issue_p2p_invitation_request23a(struct rtw_adapter *padapter, u8* raddr);
-#endif /* CONFIG_8723AU_P2P */
void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms);
void issue_probersp23a(struct rtw_adapter *padapter, unsigned char *da,
u8 is_valid_p2p_probereq);
int try_cnt, int wait_ms);
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, unsigned char *raddr,
- unsigned char action, unsigned short status);
+void issue_action_BA23a(struct rtw_adapter *padapter,
+ const unsigned char *raddr,
+ unsigned char action, unsigned short status);
unsigned int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr);
unsigned int send_beacon23a(struct rtw_adapter *padapter);
void start_clnt_join23a(struct rtw_adapter *padapter);
void start_create_ibss23a(struct rtw_adapter *padapter);
-unsigned int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int DoReserved23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-
-unsigned int on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnAction23a_back23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int on_action_public23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-unsigned int OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-
void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, int join_res);
void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter);
void process_addba_req23a(struct rtw_adapter *padapter, u8 *paddba_req, u8 *addr);
-void update_TSF23a(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len);
void correct_TSF23a(struct rtw_adapter *padapter, struct mlme_ext_priv *pmlmeext);
struct cmd_hdl {
uint parmsize;
- u8 (*h2cfuns)(struct rtw_adapter *padapter, u8 *pbuf);
+ u8 (*h2cfuns)(struct rtw_adapter *padapter, const u8 *pbuf);
};
u8 write_rfreg_hdl(struct rtw_adapter *padapter, u8 *pbuf);
-u8 NULL_hdl23a(struct rtw_adapter *padapter, u8 *pbuf);
-u8 join_cmd_hdl23a(struct rtw_adapter *padapter, u8 *pbuf);
-u8 disconnect_hdl23a(struct rtw_adapter *padapter, u8 *pbuf);
-u8 createbss_hdl23a(struct rtw_adapter *padapter, u8 *pbuf);
-u8 setopmode_hdl23a(struct rtw_adapter *padapter, u8 *pbuf);
-u8 sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, u8 *pbuf);
-u8 setauth_hdl23a(struct rtw_adapter *padapter, u8 *pbuf);
-u8 setkey_hdl23a(struct rtw_adapter *padapter, u8 *pbuf);
-u8 set_stakey_hdl23a(struct rtw_adapter *padapter, u8 *pbuf);
-u8 set_assocsta_hdl(struct rtw_adapter *padapter, u8 *pbuf);
-u8 del_assocsta_hdl(struct rtw_adapter *padapter, u8 *pbuf);
-u8 add_ba_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf);
-
-u8 mlme_evt_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf);
-u8 h2c_msg_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf);
-u8 tx_beacon_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf);
-u8 set_ch_hdl23a(struct rtw_adapter *padapter, u8 *pbuf);
-u8 set_chplan_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf);
-u8 led_blink_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf);
-u8 set_csa_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf); /* Kurt: Handling DFS channel switch announcement ie. */
-u8 tdls_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf);
+u8 NULL_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 set_assocsta_hdl(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 del_assocsta_hdl(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+
+u8 mlme_evt_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 h2c_msg_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
+u8 set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf); /* Kurt: Handling DFS channel switch announcement ie. */
+u8 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},
+++ /dev/null
-/******************************************************************************
- *
- * 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_P2P_H_
-#define __RTW_P2P_H_
-
-#include <drv_types.h>
-
-u32 build_beacon_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_probe_resp_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_prov_disc_request_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pbuf,
- u8 *pssid, u8 ussidlen, u8 *pdev_raddr);
-u32 build_assoc_resp_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pbuf,
- u8 status_code);
-u32 build_deauth_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pbuf);
-#ifdef CONFIG_8723AU_P2P
-u32 build_probe_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_probe_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf,
- u8 tunneled);
-u32 build_beacon_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_nego_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_nego_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_nego_confirm_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_invitation_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_invitation_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_assoc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_assoc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_provdisc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_provdisc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-#endif /* CONFIG_8723AU_P2P */
-
-u32 process_probe_req_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pframe,
- uint len);
-u32 process_assoc_req_p2p_ie23a(struct wifidirect_info *pwdinfo, u8 *pframe,
- uint len, struct sta_info *psta);
-u32 process_p2p_devdisc_req23a(struct wifidirect_info *pwdinfo, u8 *pframe,
- uint len);
-u32 process_p2p_devdisc_resp23a(struct wifidirect_info *pwdinfo, u8 *pframe,
- uint len);
-u8 process_p2p_provdisc_req23a(struct wifidirect_info *pwdinfo, u8 *pframe,
- uint len);
-u8 process_p2p_provdisc_resp23a(struct wifidirect_info *pwdinfo, u8 *pframe);
-u8 process_p2p_group_negotation_req23a(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len);
-u8 process_p2p_group_negotation_resp23a(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len);
-u8 process_p2p_group_negotation_confirm23a(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len);
-u8 process_p2p_presence_req23a(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len);
-
-void p2p_protocol_wk_hdl23a(struct rtw_adapter *padapter, int cmdtype);
-
-#ifdef CONFIG_8723AU_P2P
-void process_p2p_ps_ie23a(struct rtw_adapter *padapter, u8 *IEs, u32 IELength);
-void p2p_ps_wk_hdl23a(struct rtw_adapter *padapter, u8 p2p_ps_state);
-u8 p2p_ps_wk_cmd23a(struct rtw_adapter *padapter, u8 p2p_ps_state, u8 enqueue);
-#endif /* CONFIG_8723AU_P2P */
-
-void rtw_init_cfg80211_wifidirect_info(struct rtw_adapter *padapter);
-int rtw_p2p_check_frames(struct rtw_adapter *padapter, const u8 *buf,
- u32 len, u8 tx);
-void rtw_append_wfd_ie(struct rtw_adapter *padapter, u8 *buf, u32 *len);
-
-void reset_global_wifidirect_info23a(struct rtw_adapter *padapter);
-int rtw_init_wifi_display_info(struct rtw_adapter *padapter);
-void rtw_init_wifidirect_timers23a(struct rtw_adapter *padapter);
-void rtw_init_wifidirect_addrs23a(struct rtw_adapter *padapter, u8 *dev_addr,
- u8 *iface_addr);
-void init_wifidirect_info23a(struct rtw_adapter *padapter, enum P2P_ROLE role);
-int rtw_p2p_enable23a(struct rtw_adapter *padapter, enum P2P_ROLE role);
-
-static inline void _rtw_p2p_set_state(struct wifidirect_info *wdinfo,
- enum P2P_STATE state)
-{
- if (wdinfo->p2p_state != state) {
- /* wdinfo->pre_p2p_state = wdinfo->p2p_state; */
- wdinfo->p2p_state = state;
- }
-}
-
-static inline void _rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo,
- enum P2P_STATE state)
-{
- if (wdinfo->pre_p2p_state != state)
- wdinfo->pre_p2p_state = state;
-}
-
-static inline void _rtw_p2p_set_role(struct wifidirect_info *wdinfo,
- enum P2P_ROLE role)
-{
- if (wdinfo->role != role)
- wdinfo->role = role;
-}
-
-static inline int _rtw_p2p_state(struct wifidirect_info *wdinfo)
-{
- return wdinfo->p2p_state;
-}
-
-static inline int _rtw_p2p_pre_state(struct wifidirect_info *wdinfo)
-{
- return wdinfo->pre_p2p_state;
-}
-
-static inline int _rtw_p2p_role(struct wifidirect_info *wdinfo)
-{
- return wdinfo->role;
-}
-
-static inline bool _rtw_p2p_chk_state(struct wifidirect_info *wdinfo,
- enum P2P_STATE state)
-{
- return wdinfo->p2p_state == state;
-}
-
-static inline bool _rtw_p2p_chk_role(struct wifidirect_info *wdinfo,
- enum P2P_ROLE role)
-{
- return wdinfo->role == role;
-}
-
-#define rtw_p2p_set_state(wdinfo, state) _rtw_p2p_set_state(wdinfo, state)
-#define rtw_p2p_set_pre_state(wdinfo, state) \
- _rtw_p2p_set_pre_state(wdinfo, state)
-#define rtw_p2p_set_role(wdinfo, role) _rtw_p2p_set_role(wdinfo, role)
-
-#define rtw_p2p_state(wdinfo) _rtw_p2p_state(wdinfo)
-#define rtw_p2p_pre_state(wdinfo) _rtw_p2p_pre_state(wdinfo)
-#define rtw_p2p_role(wdinfo) _rtw_p2p_role(wdinfo)
-#define rtw_p2p_chk_state(wdinfo, state) _rtw_p2p_chk_state(wdinfo, state)
-#define rtw_p2p_chk_role(wdinfo, role) _rtw_p2p_chk_role(wdinfo, role)
-
-#define rtw_p2p_findphase_ex_set(wdinfo, value) \
- ((wdinfo)->find_phase_state_exchange_cnt = (value))
-
-/* is this find phase exchange for social channel scan? */
-#define rtw_p2p_findphase_ex_is_social(wdinfo) \
- ((wdinfo)->find_phase_state_exchange_cnt >= \
- P2P_FINDPHASE_EX_SOCIAL_FIRST)
-
-/* should we need find phase exchange anymore? */
-#define rtw_p2p_findphase_ex_is_needed(wdinfo) \
- ((wdinfo)->find_phase_state_exchange_cnt < P2P_FINDPHASE_EX_MAX && \
- (wdinfo)->find_phase_state_exchange_cnt != P2P_FINDPHASE_EX_NONE)
-
-#endif
struct work_struct cpwm_event;
u8 bpower_saving;
- u8 b_hw_radio_off;
u8 reg_rfoff;
u8 reg_pdnmode; /* powerdown mode */
u32 rfoff_reason;
void LPS_Enter23a(struct rtw_adapter *padapter);
void LPS_Leave23a(struct rtw_adapter *padapter);
-u8 rtw_interface_ps_func23a(struct rtw_adapter *padapter,
- enum hal_intf_ps_func efunc_id, u8 *val);
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 RXDESC_OFFSET RXDESC_SIZE
struct recv_stat {
- unsigned int rxdw0;
- unsigned int rxdw1;
- unsigned int rxdw2;
- unsigned int rxdw3;
- unsigned int rxdw4;
- unsigned int rxdw5;
+ __le32 rxdw0;
+ __le32 rxdw1;
+ __le32 rxdw2;
+ __le32 rxdw3;
+ __le32 rxdw4;
+ __le32 rxdw5;
};
/* accesser of recv_priv: rtw_recv_entry23a(dispatch / passive level); \
#define is_wep_enc(alg) (((alg) == _WEP40_) || ((alg) == _WEP104_))
-#define _WPA_IE_ID_ 0xdd
#define _WPA2_IE_ID_ 0x30
#define SHA256_MAC_LEN 32
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
};
-/* Various logical functions */
-#define RORc(x, y) \
-(((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \
-((unsigned long)(x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
-#define Ch(x, y, z) (z ^ (x & (y ^ z)))
-#define Maj(x, y, z) (((x | y) & z) | (x & y))
-#define S(x, n) RORc((x), (n))
-#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
-#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
-#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
-#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
-#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
-#ifndef MIN
-#define MIN(x, y) (((x) < (y)) ? (x) : (y))
-#endif
-
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);
struct tx_desc {
/* DWORD 0 */
- unsigned int txdw0;
- unsigned int txdw1;
- unsigned int txdw2;
- unsigned int txdw3;
- unsigned int txdw4;
- unsigned int txdw5;
- unsigned int txdw6;
- unsigned int txdw7;
+ __le32 txdw0;
+ __le32 txdw1;
+ __le32 txdw2;
+ __le32 txdw3;
+ __le32 txdw4;
+ __le32 txdw5;
+ __le32 txdw6;
+ __le32 txdw7;
};
union txdesc {
struct wlan_acl_pool acl_list;
};
-static inline u32 wifi_mac_hash(u8 *mac)
+static inline u32 wifi_mac_hash(const u8 *mac)
{
u32 x;
struct sta_info *rtw_alloc_stainfo23a(struct sta_priv *pstapriv, u8 *hwaddr);
u32 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, u8 *hwaddr);
+struct sta_info *rtw_get_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr);
u32 rtw_init_bcmc_stainfo23a(struct rtw_adapter *padapter);
struct sta_info *rtw_get_bcmc_stainfo23a(struct rtw_adapter *padapter);
u8 rtw_access_ctrl23a(struct rtw_adapter *padapter, u8 *mac_addr);
void rtl8723au_set_hw_type(struct rtw_adapter *padapter);
#define hal_set_hw_type rtl8723au_set_hw_type
-void rtl8723au_set_intf_ops(struct _io_ops *pops);
-#define usb_set_intf_ops rtl8723au_set_intf_ops
+void rtl8723au_set_intf_ops(struct rtw_adapter *padapter);
void rtl8723au_recv_tasklet(void *priv);
unsigned int ffaddr2pipehdl23a(struct dvobj_priv *pdvobj, u32 addr);
-void usb_read_mem23a(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem);
-void usb_write_mem23a(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem);
+void usb_read_mem23a(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *rmem);
+void usb_write_mem23a(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *wmem);
-void usb_read_port_cancel23a(struct intf_hdl *pintfhdl);
+void usb_read_port_cancel23a(struct rtw_adapter *adapter);
-u32 usb_write_port23a(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
- struct xmit_buf *wmem);
-void usb_write_port23a_cancel(struct intf_hdl *pintfhdl);
+u32 usb_write_port23a(struct rtw_adapter *adapter, u32 addr, u32 cnt,
+ struct xmit_buf *wmem);
+void usb_write_port23a_cancel(struct rtw_adapter *adapter);
#endif
#define SetToDs(pbuf) \
- (*(unsigned short *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_TODS))
+ (*(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_TODS))
#define SetFrDs(pbuf) \
- (*(unsigned short *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_FROMDS))
+ (*(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_FROMDS))
#define get_tofr_ds(pframe) ((ieee80211_has_tods(pframe) << 1) | \
ieee80211_has_fromds(pframe))
#define SetMFrag(pbuf) \
- (*(unsigned short *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_MOREFRAGS))
+ (*(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_MOREFRAGS))
#define ClearMFrag(pbuf) \
- (*(unsigned short *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)))
+ (*(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)))
#define SetRetry(pbuf) \
- (*(unsigned short *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_RETRY))
+ (*(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_RETRY))
#define SetPwrMgt(pbuf) \
- (*(unsigned short *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_PM))
+ (*(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_PM))
#define SetMData(pbuf) \
- (*(unsigned short *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_MOREDATA))
+ (*(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_MOREDATA))
#define SetPrivacy(pbuf) \
- (*(unsigned short *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_PROTECTED))
+ (*(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_PROTECTED))
#define SetFrameType(pbuf, type) \
do { \
- *(unsigned short *)(pbuf) &= __constant_cpu_to_le16(~(BIT(3) | BIT(2))); \
- *(unsigned short *)(pbuf) |= __constant_cpu_to_le16(type); \
+ *(__le16 *)(pbuf) &= __constant_cpu_to_le16(~(BIT(3) | BIT(2))); \
+ *(__le16 *)(pbuf) |= __constant_cpu_to_le16(type); \
} while (0)
#define SetFrameSubType(pbuf, type) \
do { \
- *(unsigned short *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2))); \
- *(unsigned short *)(pbuf) |= cpu_to_le16(type); \
+ *(__le16 *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2))); \
+ *(__le16 *)(pbuf) |= cpu_to_le16(type); \
} while (0)
#define GetTupleCache(pbuf) (cpu_to_le16(*(unsigned short *)((unsigned long)(pbuf) + 22)))
#define SetSeqNum(pbuf, num) \
do { \
- *(unsigned short *)((unsigned long)(pbuf) + 22) = \
- ((*(unsigned short *)((unsigned long)(pbuf) + 22)) & le16_to_cpu((unsigned short)0x000f)) | \
- le16_to_cpu((unsigned short)(0xfff0 & (num << 4))); \
+ *(__le16 *)((size_t)(pbuf) + 22) = \
+ ((*(__le16 *)((size_t)(pbuf) + 22)) & cpu_to_le16((unsigned short)0x000f)) | \
+ cpu_to_le16((unsigned short)(0xfff0 & (num << 4))); \
} while (0)
#define SetDuration(pbuf, dur) \
- (*(unsigned short *)((unsigned long)(pbuf) + 2) = \
+ (*(__le16 *)((unsigned long)(pbuf) + 2) = \
cpu_to_le16(0xffff & (dur)))
#define SetPriority(pbuf, tid) \
- (*(unsigned short *)(pbuf) |= cpu_to_le16(tid & 0xf))
+ (*(__le16 *)(pbuf) |= cpu_to_le16(tid & 0xf))
#define SetEOSP(pbuf, eosp) \
- (*(unsigned short *)(pbuf) |= cpu_to_le16((eosp & 1) << 4))
+ (*(__le16 *)(pbuf) |= cpu_to_le16((eosp & 1) << 4))
#define SetAckpolicy(pbuf, ack) \
- (*(unsigned short *)(pbuf) |= cpu_to_le16((ack & 3) << 5))
+ (*(__le16 *)(pbuf) |= cpu_to_le16((ack & 3) << 5))
#define SetAMsdu(pbuf, amsdu) \
- (*(unsigned short *)(pbuf) |= cpu_to_le16((amsdu & 1) << 7))
+ (*(__le16 *)(pbuf) |= cpu_to_le16((amsdu & 1) << 7))
#define GetAid(pbuf) \
(cpu_to_le16(*(unsigned short *)((unsigned long)(pbuf) + 2)) & \
#define _FIXED_IE_LENGTH_ _BEACON_IE_OFFSET_
-#define _SSID_IE_ 0
-#define _SUPPORTEDRATES_IE_ 1
-#define _DSSET_IE_ 3
-#define _TIM_IE_ 5
-#define _IBSS_PARA_IE_ 6
-#define _COUNTRY_IE_ 7
-#define _CHLGETXT_IE_ 16
-#define _SUPPORTED_CH_IE_ 36
-#define _CH_SWTICH_ANNOUNCE_ 37 /* Secondary Channel Offset */
-#define _RSN_IE_2_ 48
-#define _SSN_IE_1_ 221
-#define _ERPINFO_IE_ 42
-#define _EXT_SUPPORTEDRATES_IE_ 50
-
-#define _HT_CAPABILITY_IE_ 45
-#define _FTIE_ 55
-#define _TIMEOUT_ITVL_IE_ 56
-#define _SRC_IE_ 59
-#define _HT_EXTRA_INFO_IE_ 61
-#define _HT_ADD_INFO_IE_ 61 /* _HT_EXTRA_INFO_IE_ */
-
-
-#define EID_BSSCoexistence 72 /* 20/40 BSS Coexistence */
-#define EID_BSSIntolerantChlReport 73
-#define _RIC_Descriptor_IE_ 75
-
-#define _LINK_ID_IE_ 101
-#define _CH_SWITCH_TIMING_ 104
-#define _PTI_BUFFER_STATUS_ 106
-#define _EXT_CAP_IE_ 127
-#define _VENDOR_SPECIFIC_IE_ 221
-#define _RESERVED47_ 47
+#define EID_BSSIntolerantChlReport 73
/* ---------------------------------------------------------------------------
Below is the fixed elements...
#define WPS_ASSOC_STATE_ASSOCIATION_FAILURE 0x03
#define WPS_ASSOC_STATE_IP_FAILURE 0x04
-/* =====================P2P Section===================== */
-/* For P2P */
-#define P2POUI 0x506F9A09
-
-/* P2P Attribute ID */
-#define P2P_ATTR_STATUS 0x00
-#define P2P_ATTR_MINOR_REASON_CODE 0x01
-#define P2P_ATTR_CAPABILITY 0x02
-#define P2P_ATTR_DEVICE_ID 0x03
-#define P2P_ATTR_GO_INTENT 0x04
-#define P2P_ATTR_CONF_TIMEOUT 0x05
-#define P2P_ATTR_LISTEN_CH 0x06
-#define P2P_ATTR_GROUP_BSSID 0x07
-#define P2P_ATTR_EX_LISTEN_TIMING 0x08
-#define P2P_ATTR_INTENTED_IF_ADDR 0x09
-#define P2P_ATTR_MANAGEABILITY 0x0A
-#define P2P_ATTR_CH_LIST 0x0B
-#define P2P_ATTR_NOA 0x0C
-#define P2P_ATTR_DEVICE_INFO 0x0D
-#define P2P_ATTR_GROUP_INFO 0x0E
-#define P2P_ATTR_GROUP_ID 0x0F
-#define P2P_ATTR_INTERFACE 0x10
-#define P2P_ATTR_OPERATING_CH 0x11
-#define P2P_ATTR_INVITATION_FLAGS 0x12
-
-/* Value of Status Attribute */
-#define P2P_STATUS_SUCCESS 0x00
-#define P2P_STATUS_FAIL_INFO_UNAVAILABLE 0x01
-#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM 0x02
-#define P2P_STATUS_FAIL_LIMIT_REACHED 0x03
-#define P2P_STATUS_FAIL_INVALID_PARAM 0x04
-#define P2P_STATUS_FAIL_REQUEST_UNABLE 0x05
-#define P2P_STATUS_FAIL_PREVOUS_PROTO_ERR 0x06
-#define P2P_STATUS_FAIL_NO_COMMON_CH 0x07
-#define P2P_STATUS_FAIL_UNKNOWN_P2PGROUP 0x08
-#define P2P_STATUS_FAIL_BOTH_GOINTENT_15 0x09
-#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVSION 0x0A
-#define P2P_STATUS_FAIL_USER_REJECT 0x0B
-
-/* Value of Inviation Flags Attribute */
-#define P2P_INVITATION_FLAGS_PERSISTENT BIT(0)
-
-#define DMP_P2P_DEVCAP_SUPPORT (P2P_DEVCAP_SERVICE_DISCOVERY | \
- P2P_DEVCAP_CLIENT_DISCOVERABILITY | \
- P2P_DEVCAP_CONCURRENT_OPERATION | \
- P2P_DEVCAP_INVITATION_PROC)
-
-#define DMP_P2P_GRPCAP_SUPPORT (P2P_GRPCAP_INTRABSS)
-
-/* Value of Device Capability Bitmap */
-#define P2P_DEVCAP_SERVICE_DISCOVERY BIT(0)
-#define P2P_DEVCAP_CLIENT_DISCOVERABILITY BIT(1)
-#define P2P_DEVCAP_CONCURRENT_OPERATION BIT(2)
-#define P2P_DEVCAP_INFRA_MANAGED BIT(3)
-#define P2P_DEVCAP_DEVICE_LIMIT BIT(4)
-#define P2P_DEVCAP_INVITATION_PROC BIT(5)
-
-/* Value of Group Capability Bitmap */
-#define P2P_GRPCAP_GO BIT(0)
-#define P2P_GRPCAP_PERSISTENT_GROUP BIT(1)
-#define P2P_GRPCAP_GROUP_LIMIT BIT(2)
-#define P2P_GRPCAP_INTRABSS BIT(3)
-#define P2P_GRPCAP_CROSS_CONN BIT(4)
-#define P2P_GRPCAP_PERSISTENT_RECONN BIT(5)
-#define P2P_GRPCAP_GROUP_FORMATION BIT(6)
-
/* P2P Public Action Frame ( Management Frame ) */
#define P2P_PUB_ACTION_ACTION 0x09
#define P2P_PROVISION_DISC_REQ 7
#define P2P_PROVISION_DISC_RESP 8
-/* P2P Action Frame Type */
-#define P2P_NOTICE_OF_ABSENCE 0
-#define P2P_PRESENCE_REQUEST 1
-#define P2P_PRESENCE_RESPONSE 2
-#define P2P_GO_DISC_REQUEST 3
-
-
-#define P2P_MAX_PERSISTENT_GROUP_NUM 10
-
-#define P2P_PROVISIONING_SCAN_CNT 3
-
-#define P2P_WILDCARD_SSID_LEN 7
-
-#define P2P_FINDPHASE_EX_NONE 0 /* default value, used when: (1)p2p disabed or (2)p2p enabled but only do 1 scan phase */
-#define P2P_FINDPHASE_EX_FULL 1 /* used when p2p enabled and want to do 1 scan phase and P2P_FINDPHASE_EX_MAX-1 find phase */
-#define P2P_FINDPHASE_EX_SOCIAL_FIRST (P2P_FINDPHASE_EX_FULL+1)
-#define P2P_FINDPHASE_EX_MAX 4
-#define P2P_FINDPHASE_EX_SOCIAL_LAST P2P_FINDPHASE_EX_MAX
-
-#define P2P_PROVISION_TIMEOUT 5000 /*5 sec timeout for sending the provision discovery request */
-#define P2P_CONCURRENT_PROVISION_TIMEOUT 3000 /*3 sec timeout for sending the provision discovery request under concurrent mode */
-#define P2P_GO_NEGO_TIMEOUT 5000 /*5 sec timeout for receiving the group negotation response */
-#define P2P_CONCURRENT_GO_NEGO_TIMEOUT 3000 /*3 sec timeout for sending the negotiation request under concurrent mode */
-#define P2P_TX_PRESCAN_TIMEOUT 100 /*100ms */
-#define P2P_INVITE_TIMEOUT 5000 /*5 sec timeout for sending the invitation request */
-#define P2P_CONCURRENT_INVITE_TIMEOUT 3000 /*3 sec timeout for sending the invitation request under concurrent mode */
-#define P2P_RESET_SCAN_CH 25000 /*25 sec t/o to reset the scan channel ( based on channel plan ) */
-#define P2P_MAX_INTENT 15
-
-#define P2P_MAX_NOA_NUM 2
-
/* WPS Configuration Method */
#define WPS_CM_NONE 0x0000
#define WPS_CM_LABEL 0x0004
#define WPS_CM_SW_DISPLAY_PIN 0x2008
#define WPS_CM_LCD_DISPLAY_PIN 0x4008
-enum P2P_ROLE {
- P2P_ROLE_DISABLE = 0,
- P2P_ROLE_DEVICE = 1,
- P2P_ROLE_CLIENT = 2,
- P2P_ROLE_GO = 3
-};
-
-enum P2P_STATE {
- P2P_STATE_NONE = 0, /*P2P disable */
- P2P_STATE_IDLE = 1, /*P2P had enabled and do nothing */
- P2P_STATE_LISTEN = 2, /*In pure listen state */
- P2P_STATE_SCAN = 3, /*In scan phase */
- P2P_STATE_FIND_PHASE_LISTEN = 4, /*In the listen state of find phase */
- P2P_STATE_FIND_PHASE_SEARCH = 5, /*In the search state of find phase */
- P2P_STATE_TX_PROVISION_DIS_REQ = 6, /*In P2P provisioning discovery */
- P2P_STATE_RX_PROVISION_DIS_RSP = 7,
- P2P_STATE_RX_PROVISION_DIS_REQ = 8,
- P2P_STATE_GONEGO_ING = 9, /*Doing the group owner negoitation handshake */
- P2P_STATE_GONEGO_OK = 10, /*finish the group negoitation handshake with success */
- P2P_STATE_GONEGO_FAIL = 11, /*finish the group negoitation handshake with failure */
- P2P_STATE_RECV_INVITE_REQ_MATCH = 12, /*receiving the P2P Inviation request and match with the profile. */
- P2P_STATE_PROVISIONING_ING = 13, /*Doing the P2P WPS */
- P2P_STATE_PROVISIONING_DONE = 14, /*Finish the P2P WPS */
- P2P_STATE_TX_INVITE_REQ = 15, /*Transmit the P2P Invitation request */
- P2P_STATE_RX_INVITE_RESP_OK = 16, /*Receiving the P2P Invitation response */
- P2P_STATE_RECV_INVITE_REQ_DISMATCH = 17,/*receiving the P2P Inviation request and dismatch with the profile. */
- P2P_STATE_RECV_INVITE_REQ_GO = 18, /*receiving the P2P Inviation request and this wifi is GO. */
- P2P_STATE_RECV_INVITE_REQ_JOIN = 19, /*receiving the P2P Inviation request to join an existing P2P Group. */
- P2P_STATE_RX_INVITE_RESP_FAIL = 20, /*receiving the P2P Inviation response with failure */
- P2P_STATE_RX_INFOR_NOREADY = 21, /*receiving p2p negotiation response with information is not available */
- P2P_STATE_TX_INFOR_NOREADY = 22, /*sending p2p negotiation response with information is not available */
-};
-
-enum P2P_WPSINFO {
- P2P_NO_WPSINFO = 0,
- P2P_GOT_WPSINFO_PEER_DISPLAY_PIN = 1,
- P2P_GOT_WPSINFO_SELF_DISPLAY_PIN = 2,
- P2P_GOT_WPSINFO_PBC = 3,
-};
-
-#define P2P_PRIVATE_IOCTL_SET_LEN 64
-
-enum P2P_PROTO_WK_ID {
- P2P_FIND_PHASE_WK = 0,
- P2P_RESTORE_STATE_WK = 1,
- P2P_PRE_TX_PROVDISC_PROCESS_WK = 2,
- P2P_PRE_TX_NEGOREQ_PROCESS_WK = 3,
- P2P_PRE_TX_INVITEREQ_PROCESS_WK = 4,
- P2P_AP_P2P_CH_SWITCH_PROCESS_WK = 5,
- P2P_RO_CH_WK = 6,
-};
-
-#ifdef CONFIG_8723AU_P2P
-enum P2P_PS_STATE {
- P2P_PS_DISABLE = 0,
- P2P_PS_ENABLE = 1,
- P2P_PS_SCAN = 2,
- P2P_PS_SCAN_DONE = 3,
- P2P_PS_ALLSTASLEEP = 4, /* for P2P GO */
-};
-
-enum P2P_PS_MODE {
- P2P_PS_NONE = 0,
- P2P_PS_CTWINDOW = 1,
- P2P_PS_NOA = 2,
- P2P_PS_MIX = 3, /* CTWindow and NoA */
-};
-#endif /* CONFIG_8723AU_P2P */
-
-/* =====================WFD Section===================== */
-/* For Wi-Fi Display */
-#define WFD_ATTR_DEVICE_INFO 0x00
-#define WFD_ATTR_ASSOC_BSSID 0x01
-#define WFD_ATTR_COUPLED_SINK_INFO 0x06
-#define WFD_ATTR_LOCAL_IP_ADDR 0x08
-#define WFD_ATTR_SESSION_INFO 0x09
-#define WFD_ATTR_ALTER_MAC 0x0a
-
-/* For WFD Device Information Attribute */
-#define WFD_DEVINFO_SOURCE 0x0000
-#define WFD_DEVINFO_PSINK 0x0001
-#define WFD_DEVINFO_SSINK 0x0002
-#define WFD_DEVINFO_DUAL 0x0003
-
-#define WFD_DEVINFO_SESSION_AVAIL 0x0010
-#define WFD_DEVINFO_WSD 0x0040
-#define WFD_DEVINFO_PC_TDLS 0x0080
-#define WFD_DEVINFO_HDCP_SUPPORT 0x0100
-
#endif /* _WIFI_H_ */
#include <osdep_service.h>
#include <drv_types.h>
-struct pkt_file {
- struct sk_buff *pkt;
- __kernel_size_t pkt_len; /* the remainder length of the open_file */
- unsigned char *cur_buffer;
- u8 *buf_start;
- u8 *cur_addr;
- __kernel_size_t buf_len;
-};
-
#define NR_XMITFRAME 256
-struct xmit_priv;
-struct pkt_attrib;
-struct sta_xmit_priv;
-struct xmit_frame;
-struct xmit_buf;
-
int rtw_xmit23a_entry23a(struct sk_buff *pkt, struct net_device *pnetdev);
void rtw_os_xmit_schedule23a(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);
-uint rtw_remainder_len23a(struct pkt_file *pfile);
-void _rtw_open_pktfile23a(struct sk_buff *pkt, struct pkt_file *pfile);
-uint _rtw_pktfile_read23a(struct pkt_file *pfile, u8 *rmem, uint rlen);
-int rtw_endofpktfile23a(struct pkt_file *pfile);
void rtw_os_pkt_complete23a(struct rtw_adapter *padapter, struct sk_buff *pkt);
void rtw_os_xmit_complete23a(struct rtw_adapter *padapter,
size_t notify_ielen;
s32 notify_signal;
u8 buf[MAX_BSSINFO_LEN], *pbuf;
- size_t len, bssinf_len = 0;
+ size_t len;
struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- u8 bc_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ __le16 *fctrl;
struct wireless_dev *wdev = padapter->rtw_wdev;
struct wiphy *wiphy = wdev->wiphy;
/* DBG_8723A("%s\n", __func__); */
- bssinf_len =
- pnetwork->network.IELength + sizeof(struct ieee80211_hdr_3addr);
- if (bssinf_len > MAX_BSSINFO_LEN) {
+ if (pnetwork->network.IELength > MAX_IE_SZ) {
DBG_8723A("%s IE Length too long > %d byte\n", __func__,
- MAX_BSSINFO_LEN);
+ MAX_IE_SZ);
goto exit;
}
notify_channel = ieee80211_get_channel(wiphy, freq);
- /* rtw_get_timestampe_from_ie23a() */
notify_timestamp = jiffies_to_msecs(jiffies) * 1000; /* uSec */
notify_interval =
le16_to_cpu(*(u16 *)
rtw_get_beacon_interval23a_from_ie(pnetwork->network.IEs));
notify_capability =
- le16_to_cpu(*(u16 *)
+ get_unaligned_le16(
rtw_get_capability23a_from_ie(pnetwork->network.IEs));
notify_ie = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
SetSeqNum(pwlanhdr, 0);
if (pnetwork->network.reserved == 1) { /* WIFI_BEACON */
- memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
+ eth_broadcast_addr(pwlanhdr->addr1);
SetFrameSubType(pbuf, WIFI_BEACON);
} else {
memcpy(pwlanhdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_network *cur_network = &pmlmepriv->cur_network;
struct wireless_dev *pwdev = padapter->rtw_wdev;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif
DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
return;
-#ifdef CONFIG_8723AU_P2P
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- DBG_8723A("%s, role =%d, p2p_state =%d, pre_p2p_state =%d\n",
- __func__, rtw_p2p_role(pwdinfo),
- rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
- }
-#endif /* CONFIG_8723AU_P2P */
-
- if (rtw_to_roaming(padapter) > 0) {
+ if (padapter->mlmepriv.to_roaming > 0) {
struct wiphy *wiphy = pwdev->wiphy;
struct ieee80211_channel *notify_channel;
u32 freq;
{
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wireless_dev *pwdev = padapter->rtw_wdev;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif
DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
return;
-#ifdef CONFIG_8723AU_P2P
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- del_timer_sync(&pwdinfo->find_phase_timer);
- del_timer_sync(&pwdinfo->restore_p2p_state_timer);
- del_timer_sync(&pwdinfo->pre_tx_scan_timer);
-
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
-
- DBG_8723A("%s, role =%d, p2p_state =%d, pre_p2p_state =%d\n",
- __func__, rtw_p2p_role(pwdinfo),
- rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
- }
-#endif /* CONFIG_8723AU_P2P */
-
if (!padapter->mlmepriv.not_indic_disco) {
if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING)) {
cfg80211_connect_result(padapter->pnetdev, NULL, NULL,
pcmd->rsp = NULL;
pcmd->rspsz = 0;
- INIT_LIST_HEAD(&pcmd->list);
-
res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
exit:
struct rtw_adapter *padapter = netdev_priv(dev);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct security_priv *psecuritypriv = &padapter->securitypriv;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif /* CONFIG_8723AU_P2P */
-
-
DBG_8723A("%s\n", __func__);
rtw_set_key23a(padapter,
&padapter->securitypriv,
param->u.crypt.idx, 1);
-#ifdef CONFIG_8723AU_P2P
- if (rtw_p2p_chk_state
- (pwdinfo,
- P2P_STATE_PROVISIONING_ING)) {
- rtw_p2p_set_state(pwdinfo,
- P2P_STATE_PROVISIONING_DONE);
- }
-#endif /* CONFIG_8723AU_P2P */
-
}
}
{
char *alg_name;
u32 param_len;
- struct ieee_param *param = NULL;
+ struct ieee_param *param;
int ret = 0;
struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
param_len = sizeof(struct ieee_param) + params->key_len;
param = kzalloc(param_len, GFP_KERNEL);
- if (param == NULL)
- return -1;
+ if (!param)
+ return -ENOMEM;
param->cmd = IEEE_CMD_SET_ENCRYPTION;
- memset(param->sta_addr, 0xff, ETH_ALEN);
+ eth_broadcast_addr(param->sta_addr);
switch (params->cipher) {
case IW_AUTH_CIPHER_NONE:
ret = -ENOENT;
goto exit;
}
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A(FUNC_NDEV_FMT " mac =" MAC_FMT "\n", FUNC_NDEV_ARG(ndev),
MAC_ARG(mac));
-#endif
/* for infra./P2PClient mode */
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif
int ret = 0;
u8 change = false;
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION:
networkType = Ndis802_11Infrastructure;
-#ifdef CONFIG_8723AU_P2P
- if (change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- del_timer_sync(&pwdinfo->find_phase_timer);
- del_timer_sync(&pwdinfo->restore_p2p_state_timer);
- del_timer_sync(&pwdinfo->pre_tx_scan_timer);
-
- /* it means remove GO and change mode from AP(GO)
- to station(P2P DEVICE) */
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
-
- DBG_8723A("%s, role =%d, p2p_state =%d, pre_p2p_state ="
- "%d\n", __func__, rtw_p2p_role(pwdinfo),
- rtw_p2p_state(pwdinfo),
- rtw_p2p_pre_state(pwdinfo));
- }
-#endif /* CONFIG_8723AU_P2P */
break;
case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_AP:
networkType = Ndis802_11APMode;
-#ifdef CONFIG_8723AU_P2P
- if (change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- /* it means P2P Group created, we will be GO
- and change mode from P2P DEVICE to AP(GO) */
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- }
-#endif /* CONFIG_8723AU_P2P */
break;
default:
return -EOPNOTSUPP;
{
spin_lock_bh(&pwdev_priv->scan_req_lock);
if (pwdev_priv->scan_request != NULL) {
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A("%s with scan req\n", __func__);
-#endif
+
if (pwdev_priv->scan_request->wiphy !=
pwdev_priv->rtw_wdev->wiphy)
DBG_8723A("error wiphy compare\n");
pwdev_priv->scan_request = NULL;
} else {
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A("%s without scan req\n", __func__);
-#endif
}
spin_unlock_bh(&pwdev_priv->scan_req_lock);
}
struct rtw_queue *queue = &pmlmepriv->scanned_queue;
struct wlan_network *pnetwork;
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A("%s\n", __func__);
-#endif
-
spin_lock_bh(&pmlmepriv->scanned_queue.lock);
phead = get_list_head(queue);
int ret = 0;
uint wps_ielen = 0;
u8 *wps_ie;
-#ifdef CONFIG_8723AU_P2P
- u32 p2p_ielen = 0;
- u8 *p2p_ie;
- u32 wfd_ielen = 0;
-#endif
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A("%s, ielen =%d\n", __func__, len);
-#endif
if (len > 0) {
wps_ie = rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen);
if (wps_ie) {
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A("probe_req_wps_ielen =%d\n", wps_ielen);
-#endif
+
if (pmlmepriv->wps_probe_req_ie) {
pmlmepriv->wps_probe_req_ie_len = 0;
kfree(pmlmepriv->wps_probe_req_ie);
memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
pmlmepriv->wps_probe_req_ie_len = wps_ielen;
}
-#ifdef CONFIG_8723AU_P2P
- p2p_ie = rtw_get_p2p_ie23a(buf, len, NULL, &p2p_ielen);
- if (p2p_ie) {
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A("probe_req_p2p_ielen =%d\n", p2p_ielen);
-#endif
-
- if (pmlmepriv->p2p_probe_req_ie) {
- pmlmepriv->p2p_probe_req_ie_len = 0;
- kfree(pmlmepriv->p2p_probe_req_ie);
- pmlmepriv->p2p_probe_req_ie = NULL;
- }
-
- pmlmepriv->p2p_probe_req_ie =
- kmalloc(p2p_ielen, GFP_KERNEL);
- if (pmlmepriv->p2p_probe_req_ie == NULL) {
- DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
- __func__, __LINE__);
- return -EINVAL;
-
- }
- memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
- pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
- }
-#endif /* CONFIG_8723AU_P2P */
-
- /* buf += p2p_ielen; */
- /* len -= p2p_ielen; */
-
-#ifdef CONFIG_8723AU_P2P
- if (rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) {
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A("probe_req_wfd_ielen =%d\n", wfd_ielen);
-#endif
-
- if (pmlmepriv->wfd_probe_req_ie) {
- pmlmepriv->wfd_probe_req_ie_len = 0;
- kfree(pmlmepriv->wfd_probe_req_ie);
- pmlmepriv->wfd_probe_req_ie = NULL;
- }
-
- pmlmepriv->wfd_probe_req_ie =
- kmalloc(wfd_ielen, GFP_KERNEL);
- if (pmlmepriv->wfd_probe_req_ie == NULL) {
- DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
- __func__, __LINE__);
- return -EINVAL;
-
- }
- rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie,
- &pmlmepriv->wfd_probe_req_ie_len);
- }
-#endif /* CONFIG_8723AU_P2P */
-
}
return ret;
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;
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- int social_channel = 0;
-#endif /* CONFIG_8723AU_P2P */
bool need_indicate_scan_done = false;
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter));
-#endif
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)) {
-
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A("%s under WIFI_AP_STATE\n", __func__);
-#endif
/* need_indicate_scan_done = true; */
/* goto check_need_indicate_scan_done; */
}
need_indicate_scan_done = true;
goto check_need_indicate_scan_done;
}
-#ifdef CONFIG_8723AU_P2P
- if (!memcmp(ssids->ssid, "DIRECT-", 7) &&
- rtw_get_p2p_ie23a((u8 *) request->ie, request->ie_len, NULL, NULL)) {
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- rtw_p2p_enable23a(padapter, P2P_ROLE_DEVICE);
- wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = true;
- } else {
- rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A("%s, role =%d, p2p_state =%d\n", __func__,
- rtw_p2p_role(pwdinfo),
- rtw_p2p_state(pwdinfo));
-#endif
- }
- rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
-
- if (request->n_channels == 3 &&
- request->channels[0]->hw_value == 1 &&
- request->channels[1]->hw_value == 6 &&
- request->channels[2]->hw_value == 11)
- social_channel = 1;
- }
-#endif /* CONFIG_8723AU_P2P */
if (request->ie && request->ie_len > 0) {
rtw_cfg80211_set_probe_req_wpsp2pie(padapter,
need_indicate_scan_done = true;
goto check_need_indicate_scan_done;
}
-#ifdef CONFIG_8723AU_P2P
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
- !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
- rtw_free_network_queue23a(padapter, true);
-
- if (social_channel == 0)
- rtw_p2p_findphase_ex_set(pwdinfo,
- P2P_FINDPHASE_EX_NONE);
- else
- rtw_p2p_findphase_ex_set(pwdinfo,
- P2P_FINDPHASE_EX_SOCIAL_LAST);
- }
-#endif /* CONFIG_8723AU_P2P */
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++) {
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A("ssid =%s, len =%d\n", ssids[i].ssid,
ssids[i].ssid_len);
-#endif
memcpy(ssid[i].ssid, ssids[i].ssid, ssids[i].ssid_len);
ssid[i].ssid_len = ssids[i].ssid_len;
}
if (request->n_channels == 1) {
for (i = 0; i < request->n_channels &&
i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A(FUNC_ADPT_FMT CHAN_FMT "\n",
FUNC_ADPT_ARG(padapter),
CHAN_ARG(request->channels[i]));
-#endif
ch[i].hw_value = request->channels[i]->hw_value;
ch[i].flags = request->channels[i]->flags;
}
static int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie,
size_t ielen)
{
- u8 *buf = NULL, *pos = NULL;
+ u8 *buf = NULL;
int group_cipher = 0, pairwise_cipher = 0;
int ret = 0;
- int wpa_ielen = 0;
- int wpa2_ielen = 0;
- u8 *pwpa, *pwpa2;
- u8 null_addr[] = { 0, 0, 0, 0, 0, 0 };
+ const u8 *pwpa, *pwpa2;
int i;
if (!pie || !ielen) {
buf[i], buf[i + 1],
buf[i + 2], buf[i + 3], buf[i + 4],
buf[i + 5], buf[i + 6], buf[i + 7]);
- pos = buf;
if (ielen < RSN_HEADER_LEN) {
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
("Ie len too short %d\n", (int)ielen));
goto exit;
}
- pwpa = rtw_get_wpa_ie23a(buf, &wpa_ielen, ielen);
- if (pwpa && wpa_ielen > 0) {
- if (rtw_parse_wpa_ie23a(pwpa, wpa_ielen + 2, &group_cipher,
- &pairwise_cipher, NULL) == _SUCCESS) {
+ pwpa = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPA,
+ buf, 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[0],
- wpa_ielen + 2);
+ memcpy(padapter->securitypriv.supplicant_ie, pwpa,
+ pwpa[1] + 2);
- DBG_8723A("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
+ DBG_8723A("got wpa_ie, wpa_ielen:%u\n", pwpa[1]);
}
}
- pwpa2 = rtw_get_wpa2_ie23a(buf, &wpa2_ielen, ielen);
- if (pwpa2 && wpa2_ielen > 0) {
- if (rtw_parse_wpa2_ie23a (pwpa2, wpa2_ielen + 2, &group_cipher,
- &pairwise_cipher, NULL) == _SUCCESS) {
+ pwpa2 = cfg80211_find_ie(WLAN_EID_RSN, buf, 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[0],
- wpa2_ielen + 2);
+ memcpy(padapter->securitypriv.supplicant_ie, pwpa2,
+ pwpa2[1] + 2);
- DBG_8723A("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
+ DBG_8723A("got wpa2_ie, wpa2_ielen:%u\n", pwpa2[1]);
}
}
}
}
-#ifdef CONFIG_8723AU_P2P
- { /* check p2p_ie for assoc req; */
- uint p2p_ielen = 0;
- u8 *p2p_ie;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- p2p_ie = rtw_get_p2p_ie23a(buf, ielen, NULL, &p2p_ielen);
- if (p2p_ie) {
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A("%s p2p_assoc_req_ielen =%d\n", __func__,
- p2p_ielen);
-#endif
-
- if (pmlmepriv->p2p_assoc_req_ie) {
- pmlmepriv->p2p_assoc_req_ie_len = 0;
- kfree(pmlmepriv->p2p_assoc_req_ie);
- pmlmepriv->p2p_assoc_req_ie = NULL;
- }
-
- pmlmepriv->p2p_assoc_req_ie =
- kmalloc(p2p_ielen, GFP_KERNEL);
- if (pmlmepriv->p2p_assoc_req_ie == NULL) {
- DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
- __func__, __LINE__);
- goto exit;
- }
- memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
- pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
- }
- }
-#endif /* CONFIG_8723AU_P2P */
-
-#ifdef CONFIG_8723AU_P2P
- { /* check wfd_ie for assoc req; */
- uint wfd_ielen = 0;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- if (rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen)) {
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A("%s wfd_assoc_req_ielen =%d\n", __func__,
- wfd_ielen);
-#endif
-
- if (pmlmepriv->wfd_assoc_req_ie) {
- pmlmepriv->wfd_assoc_req_ie_len = 0;
- kfree(pmlmepriv->wfd_assoc_req_ie);
- pmlmepriv->wfd_assoc_req_ie = NULL;
- }
-
- pmlmepriv->wfd_assoc_req_ie =
- kmalloc(wfd_ielen, GFP_KERNEL);
- if (pmlmepriv->wfd_assoc_req_ie == NULL) {
- DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
- __func__, __LINE__);
- goto exit;
- }
- rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie,
- &pmlmepriv->wfd_assoc_req_ie_len);
- }
- }
-#endif /* CONFIG_8723AU_P2P */
-
/* TKIP and AES disallow multicast packets until installing group key */
if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_ ||
padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_ ||
padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
/* WPS open need to enable multicast */
/* check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true)*/
- rtw_hal_set_hwreg23a(padapter, HW_VAR_OFF_RCR_AM, null_addr);
+ rtl8723a_off_rcr_am(padapter);
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->"
if (!memcmp(psecuritypriv->PMKIDList[index].Bssid,
pmksa->bssid, ETH_ALEN)) {
/* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
- memset(psecuritypriv->PMKIDList[index].Bssid, 0x00,
- ETH_ALEN);
+ eth_zero_addr(psecuritypriv->PMKIDList[index].Bssid);
memset(psecuritypriv->PMKIDList[index].PMKID, 0x00,
WLAN_PMKID_LEN);
psecuritypriv->PMKIDList[index].bUsed = false;
u8 *pmgmt_frame;
uint frame_len;
struct ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
+ __le16 *fctrl;
u8 mgmt_buf[128] = { 0 };
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
u32 len = skb->len;
u8 category, action;
-#ifdef CONFIG_8723AU_P2P
- int type = -1;
-#endif
if (rtw_action_frame_parse23a(skb->data, len, &category,
&action) == false) {
DBG_8723A("RTW_Tx:da =" MAC_FMT " via " FUNC_NDEV_FMT "\n",
MAC_ARG(dot11_hdr->addr1), FUNC_NDEV_ARG(ndev));
-#ifdef CONFIG_8723AU_P2P
- type = rtw_p2p_check_frames(padapter, skb->data, len, true);
- if (type >= 0)
- goto dump;
-#endif
if (category == WLAN_CATEGORY_PUBLIC)
DBG_8723A("RTW_Tx:%s\n", action_public_str23a(action));
else
DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category,
action);
-#ifdef CONFIG_8723AU_P2P
-dump:
-#endif
+
/* starting alloc mgmt frame to dump it */
pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
if (pmgntframe == NULL)
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
memcpy(pframe, skb->data, len);
-#ifdef CONFIG_8723AU_P2P
- if (type >= 0) {
- struct wifi_display_info *pwfd_info;
-
- pwfd_info = padapter->wdinfo.wfd_info;
-
- if (pwfd_info->wfd_enable)
- rtw_append_wfd_ie(padapter, pframe, &len);
- }
-#endif /* CONFIG_8723AU_P2P */
pattrib->pktlen = len;
/* update seq number */
int ret = 0;
u8 *pbuf = NULL;
uint len, wps_ielen = 0;
-#ifdef CONFIG_8723AU_P2P
- uint p2p_ielen = 0;
- u8 got_p2p_ie = false;
-#endif
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
/* struct sta_priv *pstapriv = &padapter->stapriv; */
&wps_ielen))
DBG_8723A("add bcn, wps_ielen =%d\n", wps_ielen);
-#ifdef CONFIG_8723AU_P2P
- /* check p2p ie if inclued */
- if (rtw_get_p2p_ie23a
- (pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL,
- &p2p_ielen)) {
- DBG_8723A("got p2p_ie, len =%d\n", p2p_ielen);
- got_p2p_ie = true;
- }
-#endif
-
/* pbss_network->IEs will not include p2p_ie, wfd ie */
- rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_,
- P2P_OUI23A, 4);
- rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_,
- WFD_OUI23A, 4);
+ rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_,
+ WLAN_EID_VENDOR_SPECIFIC, P2P_OUI23A, 4);
+ rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_,
+ WLAN_EID_VENDOR_SPECIFIC, WFD_OUI23A, 4);
if (rtw_check_beacon_data23a(adapter, pbuf, len) == _SUCCESS) {
-#ifdef CONFIG_8723AU_P2P
- /* check p2p if enable */
- if (got_p2p_ie == true) {
- struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- DBG_8723A("Enable P2P function for the first "
- "time\n");
- rtw_p2p_enable23a(adapter, P2P_ROLE_GO);
- wdev_to_priv(adapter->rtw_wdev)->p2p_enabled =
- true;
- } else {
- del_timer_sync(&pwdinfo->find_phase_timer);
- del_timer_sync(&pwdinfo->
- restore_p2p_state_timer);
- del_timer_sync(&pwdinfo->pre_tx_scan_timer);
-
- DBG_8723A("enter GO Mode, p2p_ielen =%d\n",
- p2p_ielen);
-
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- pwdinfo->intent = 15;
- }
-
- pwdinfo->operating_channel = pmlmeext->cur_channel;
- }
-#endif /* CONFIG_8723AU_P2P */
-
ret = 0;
-
} else {
ret = -EINVAL;
}
void rtw_cfg80211_rx_action_p2p(struct rtw_adapter *padapter, u8 *pmgmt_frame,
uint frame_len)
{
-#ifdef CONFIG_8723AU_P2P
- int type;
-#endif
s32 freq;
int channel;
u8 category, action;
channel = rtw_get_oper_ch23a(padapter);
DBG_8723A("RTW_Rx:cur_ch =%d\n", channel);
-#ifdef CONFIG_8723AU_P2P
- type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, false);
- if (type >= 0)
- goto indicate;
-#endif
rtw_action_frame_parse23a(pmgmt_frame, frame_len, &category, &action);
DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action);
-#ifdef CONFIG_8723AU_P2P
-indicate:
-#endif
if (channel <= RTW_CH_MAX_2G_CHANNEL)
freq = ieee80211_channel_to_frequency(channel,
IEEE80211_BAND_2GHZ);
void rtw_cfg80211_rx_p2p_action_public(struct rtw_adapter *padapter,
u8 *pmgmt_frame, uint frame_len)
{
-#ifdef CONFIG_8723AU_P2P
- int type;
-#endif
s32 freq;
int channel;
u8 category, action;
channel = rtw_get_oper_ch23a(padapter);
DBG_8723A("RTW_Rx:cur_ch =%d\n", channel);
-#ifdef CONFIG_8723AU_P2P
- type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, false);
- if (type >= 0) {
- switch (type) {
- case P2P_GO_NEGO_CONF:
- case P2P_PROVISION_DISC_RESP:
- rtw_clear_scan_deny(padapter);
- }
- goto indicate;
- }
-#endif
rtw_action_frame_parse23a(pmgmt_frame, frame_len, &category, &action);
DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action);
-#ifdef CONFIG_8723AU_P2P
-indicate:
-#endif
if (channel <= RTW_CH_MAX_2G_CHANNEL)
freq = ieee80211_channel_to_frequency(channel,
IEEE80211_BAND_2GHZ);
rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
}
-#ifdef CONFIG_8723AU_P2P
-void rtw_cfg80211_issue_p2p_provision_request23a(struct rtw_adapter *padapter,
- const u8 *buf, size_t len)
-{
- u16 wps_devicepassword_id = 0x0000;
- uint wps_devicepassword_id_len = 0;
- u8 wpsie[255] = { 0x00 }, p2p_ie[255] = { 0x00 };
- uint p2p_ielen = 0;
- uint wpsielen = 0;
- u32 devinfo_contentlen = 0;
- u8 devinfo_content[64] = { 0x00 };
- u16 capability = 0;
- uint capability_len = 0;
-
- unsigned char category = WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- u8 dialogToken = 1;
- u32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_PROVISION_DISC_REQ;
- u32 p2pielen = 0;
-#ifdef CONFIG_8723AU_P2P
- u32 wfdielen = 0;
-#endif /* CONFIG_8723AU_P2P */
-
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr, *hdr;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 *frame_body =
- (unsigned char *)(buf + sizeof(struct ieee80211_hdr_3addr));
- size_t frame_body_len = len - sizeof(struct ieee80211_hdr_3addr);
-
- DBG_8723A("[%s] In\n", __func__);
-
- hdr = (struct ieee80211_hdr *)buf;
- /* prepare for building provision_request frame */
- memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, hdr->addr1, ETH_ALEN);
- memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, hdr->addr1, ETH_ALEN);
-
- pwdinfo->tx_prov_disc_info.wps_config_method_request =
- WPS_CM_PUSH_BUTTON;
-
- rtw_get_wps_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_,
- frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie,
- &wpsielen);
- rtw_get_wps_attr_content23a(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID,
- (u8 *)&wps_devicepassword_id,
- &wps_devicepassword_id_len);
- wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
-
- switch (wps_devicepassword_id) {
- case WPS_DPID_PIN:
- pwdinfo->tx_prov_disc_info.wps_config_method_request =
- WPS_CM_LABEL;
- break;
- case WPS_DPID_USER_SPEC:
- pwdinfo->tx_prov_disc_info.wps_config_method_request =
- WPS_CM_DISPLYA;
- break;
- case WPS_DPID_MACHINE_SPEC:
- break;
- case WPS_DPID_REKEY:
- break;
- case WPS_DPID_PBC:
- pwdinfo->tx_prov_disc_info.wps_config_method_request =
- WPS_CM_PUSH_BUTTON;
- break;
- case WPS_DPID_REGISTRAR_SPEC:
- pwdinfo->tx_prov_disc_info.wps_config_method_request =
- WPS_CM_KEYPAD;
- break;
- default:
- break;
- }
-
- if (rtw_get_p2p_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_,
- frame_body_len - _PUBLIC_ACTION_IE_OFFSET_,
- p2p_ie, &p2p_ielen)) {
- rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen,
- P2P_ATTR_DEVICE_INFO, devinfo_content,
- &devinfo_contentlen);
- rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY,
- (u8 *)&capability, &capability_len);
- }
-
- /* start to build provision_request frame */
- memset(wpsie, 0, sizeof(wpsie));
- memset(p2p_ie, 0, sizeof(p2p_ie));
- p2p_ielen = 0;
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (pmgntframe == NULL)
- 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;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- pwlanhdr->frame_control = 0;
-
- memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr,
- ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
- memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr,
- ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *)&p2poui,
- &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
-
- /* build_prov_disc_request_p2p_ie23a */
- /* P2P OUI */
- p2pielen = 0;
- p2p_ie[p2pielen++] = 0x50;
- p2p_ie[p2pielen++] = 0x6F;
- p2p_ie[p2pielen++] = 0x9A;
- p2p_ie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20110301 */
- /* According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes */
- /* 1. P2P Capability */
- /* 2. Device Info */
- /* 3. Group ID ( When joining an operating P2P Group ) */
-
- /* P2P Capability ATTR */
- /* Type: */
- p2p_ie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- put_unaligned_le16(0x0002, p2p_ie + p2pielen);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- /* Group Capability Bitmap, 1 byte */
- memcpy(p2p_ie + p2pielen, &capability, 2);
- p2pielen += 2;
-
- /* Device Info ATTR */
- /* Type: */
- p2p_ie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- put_unaligned_le16(devinfo_contentlen, p2p_ie + p2pielen);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
- p2pielen += devinfo_contentlen;
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
- (unsigned char *)p2p_ie, &p2p_ielen);
- pattrib->pktlen += p2p_ielen;
-
- wpsielen = 0;
- /* WPS OUI */
- *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* WPS version */
- /* Type: */
- *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
- wpsielen += 2;
-
- /* Length: */
- *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
-
- /* Config Method */
- /* Type: */
- *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
- wpsielen += 2;
-
- /* Length: */
- *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
- *(u16 *)(wpsie + wpsielen) =
- cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
- wpsielen += 2;
-
- pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen,
- (unsigned char *)wpsie, &pattrib->pktlen);
-
-#ifdef CONFIG_8723AU_P2P
- wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
-#endif /* CONFIG_8723AU_P2P */
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- /* dump_mgntframe23a(padapter, pmgntframe); */
- if (dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe) != _SUCCESS)
- DBG_8723A("%s, ack to\n", __func__);
-}
-
-static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
- struct wireless_dev *wdev,
- struct ieee80211_channel *channel,
- unsigned int duration, u64 *cookie)
-{
- s32 err = 0;
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- struct cfg80211_wifidirect_info *pcfg80211_wdinfo =
- &padapter->cfg80211_wdinfo;
- u8 remain_ch =
- (u8) ieee80211_frequency_to_channel(channel->center_freq);
- u8 ready_on_channel = false;
-
- DBG_8723A(FUNC_ADPT_FMT " ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter),
- remain_ch, duration);
-
- if (pcfg80211_wdinfo->is_ro_ch == true) {
- DBG_8723A("%s, cancel ro ch timer\n", __func__);
-
- del_timer_sync(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
-
-#ifdef CONFIG_8723AU_P2P
- p2p_protocol_wk_hdl23a(padapter, P2P_RO_CH_WK);
-#endif
- }
-
- pcfg80211_wdinfo->is_ro_ch = true;
-
- if (_FAIL == rtw_pwr_wakeup(padapter)) {
- err = -EFAULT;
- goto exit;
- }
-
- memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel,
- sizeof(struct ieee80211_channel));
- pcfg80211_wdinfo->remain_on_ch_cookie = *cookie;
-
- rtw_scan_abort23a(padapter);
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- rtw_p2p_enable23a(padapter, P2P_ROLE_DEVICE);
- wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = true;
- } else {
- rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A("%s, role =%d, p2p_state =%d\n", __func__,
- rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
-#endif
- }
-
- rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
-
- if (duration < 400)
- duration = duration * 3; /* extend from exper. */
-
- pcfg80211_wdinfo->restore_channel = pmlmeext->cur_channel;
-
- if (rtw_ch_set_search_ch23a(pmlmeext->channel_set, remain_ch) >= 0) {
- if (remain_ch != pmlmeext->cur_channel) {
- ready_on_channel = true;
- }
- } else {
- DBG_8723A("%s remain_ch:%u not in channel plan!!!!\n",
- __func__, remain_ch);
- }
-
- /* call this after other things have been done */
- if (ready_on_channel == true) {
- if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
- pmlmeext->cur_channel = remain_ch;
-
- set_channel_bwmode23a(padapter, remain_ch,
- HAL_PRIME_CHNL_OFFSET_DONT_CARE,
- HT_CHANNEL_WIDTH_20);
- }
- }
- DBG_8723A("%s, set ro ch timer, duration =%d\n", __func__, duration);
- mod_timer(&pcfg80211_wdinfo->remain_on_ch_timer,
- jiffies + msecs_to_jiffies(duration));
-
- rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type,
- duration, GFP_KERNEL);
-
- pwdinfo->listen_channel = pmlmeext->cur_channel;
-
-exit:
- if (err)
- pcfg80211_wdinfo->is_ro_ch = false;
-
- return err;
-}
-
-static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
- struct wireless_dev *wdev,
- u64 cookie)
-{
- s32 err = 0;
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- struct cfg80211_wifidirect_info *pcfg80211_wdinfo =
- &padapter->cfg80211_wdinfo;
-
- DBG_8723A(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter));
-
- if (pcfg80211_wdinfo->is_ro_ch == true) {
- DBG_8723A("%s, cancel ro ch timer\n", __func__);
- del_timer_sync(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
-#ifdef CONFIG_8723AU_P2P
- p2p_protocol_wk_hdl23a(padapter, P2P_RO_CH_WK);
-#endif
- }
-
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A("%s, role =%d, p2p_state =%d\n", __func__,
- rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
-#endif
- pcfg80211_wdinfo->is_ro_ch = false;
-
- return err;
-}
-
-#endif /* CONFIG_8723AU_P2P */
-
static int _cfg80211_rtw_mgmt_tx(struct rtw_adapter *padapter, u8 tx_ch,
const u8 *buf, size_t len)
{
struct ieee80211_hdr *pwlanhdr;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- /* struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; */
if (_FAIL == rtw_pwr_wakeup(padapter)) {
ret = -EFAULT;
pattrib->seqnum = pmlmeext->mgnt_seq;
pmlmeext->mgnt_seq++;
-#ifdef CONFIG_8723AU_P2P
- {
- struct wifi_display_info *pwfd_info;
-
- pwfd_info = padapter->wdinfo.wfd_info;
-
- if (true == pwfd_info->wfd_enable) {
- rtw_append_wfd_ie(padapter, pframe, &pattrib->pktlen);
- }
- }
-#endif /* CONFIG_8723AU_P2P */
-
pattrib->last_txcmdsz = pattrib->pktlen;
if (dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe) != _SUCCESS) {
ack = false;
ret = _FAIL;
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A("%s, ack == _FAIL\n", __func__);
-#endif
} else {
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A("%s, ack =%d, ok!\n", __func__, ack);
-#endif
ret = _SUCCESS;
}
exit:
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A("%s, ret =%d\n", __func__, ret);
-#endif
return ret;
}
/* cookie generation */
*cookie = (unsigned long)buf;
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A(FUNC_ADPT_FMT " len =%zu, ch =%d"
"\n", FUNC_ADPT_ARG(padapter), len, tx_ch);
-#endif /* CONFIG_DEBUG_CFG80211 */
/* indicate ack before issue frame to avoid racing with rsp frame */
rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack,
DBG_8723A("RTW_Tx:tx_ch =%d, da =" MAC_FMT "\n", tx_ch,
MAC_ARG(hdr->addr1));
-#ifdef CONFIG_8723AU_P2P
- type = rtw_p2p_check_frames(padapter, buf, len, true);
- if (type >= 0)
- goto dump;
-#endif
if (category == WLAN_CATEGORY_PUBLIC)
DBG_8723A("RTW_Tx:%s\n", action_public_str23a(action));
else
DBG_8723A("RTW_Tx:category(%u), action(%u)\n",
category, action);
-#ifdef CONFIG_8723AU_P2P
-dump:
-#endif
do {
dump_cnt++;
tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
struct wireless_dev *wdev,
u16 frame_type, bool reg)
{
-
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A(FUNC_ADPT_FMT " frame_type:%x, reg:%d\n",
- FUNC_ADPT_ARG(adapter), frame_type, reg);
-#endif
-
if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
return;
int ret = 0;
uint wps_ielen = 0;
u8 *wps_ie;
-#ifdef CONFIG_8723AU_P2P
- u32 p2p_ielen = 0;
- u32 wfd_ielen = 0;
- u8 *p2p_ie;
-#endif
#ifdef CONFIG_8723AU_AP_MODE
u8 wps_oui[8] = { 0x0, 0x50, 0xf2, 0x04 };
#endif
if (len > 0) {
wps_ie = rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen);
if (wps_ie) {
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A("bcn_wps_ielen =%d\n", wps_ielen);
-#endif
if (pmlmepriv->wps_beacon_ie) {
pmlmepriv->wps_beacon_ie_len = 0;
pmlmepriv->wps_beacon_ie_len = wps_ielen;
#ifdef CONFIG_8723AU_AP_MODE
- update_beacon23a(padapter, _VENDOR_SPECIFIC_IE_, wps_oui,
- true);
-#endif
- }
-#ifdef CONFIG_8723AU_P2P
- p2p_ie = rtw_get_p2p_ie23a(buf, len, NULL, &p2p_ielen);
- if (p2p_ie) {
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A("bcn_p2p_ielen =%d\n", p2p_ielen);
-#endif
-
- if (pmlmepriv->p2p_beacon_ie) {
- pmlmepriv->p2p_beacon_ie_len = 0;
- kfree(pmlmepriv->p2p_beacon_ie);
- pmlmepriv->p2p_beacon_ie = NULL;
- }
-
- pmlmepriv->p2p_beacon_ie =
- kmalloc(p2p_ielen, GFP_KERNEL);
- if (pmlmepriv->p2p_beacon_ie == NULL) {
- DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
- __func__, __LINE__);
- return -EINVAL;
- }
-
- memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
- pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
- }
-#endif /* CONFIG_8723AU_P2P */
-
- /* buf += p2p_ielen; */
- /* len -= p2p_ielen; */
-
-#ifdef CONFIG_8723AU_P2P
- if (rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) {
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A("bcn_wfd_ielen =%d\n", wfd_ielen);
+ update_beacon23a(padapter, WLAN_EID_VENDOR_SPECIFIC,
+ wps_oui, true);
#endif
-
- if (pmlmepriv->wfd_beacon_ie) {
- pmlmepriv->wfd_beacon_ie_len = 0;
- kfree(pmlmepriv->wfd_beacon_ie);
- pmlmepriv->wfd_beacon_ie = NULL;
- }
-
- pmlmepriv->wfd_beacon_ie =
- kmalloc(wfd_ielen, GFP_KERNEL);
- if (pmlmepriv->wfd_beacon_ie == NULL) {
- DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
- __func__, __LINE__);
- return -EINVAL;
-
- }
- rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie,
- &pmlmepriv->wfd_beacon_ie_len);
}
-#endif /* CONFIG_8723AU_P2P */
pmlmeext->bstart_bss = true;
{
struct rtw_adapter *padapter = netdev_priv(net);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-#ifdef CONFIG_8723AU_P2P
- u32 p2p_ielen = 0;
- u8 *p2p_ie;
- u32 wfd_ielen = 0;
-#endif
int ret = 0;
uint wps_ielen = 0;
u8 *wps_ie;
}
- /* buf += wps_ielen; */
- /* len -= wps_ielen; */
-
-#ifdef CONFIG_8723AU_P2P
- p2p_ie = rtw_get_p2p_ie23a(buf, len, NULL, &p2p_ielen);
- if (p2p_ie) {
- u8 is_GO = false;
- u32 attr_contentlen = 0;
- u16 cap_attr = 0;
-
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A("probe_resp_p2p_ielen =%d\n", p2p_ielen);
-#endif
-
- /* Check P2P Capability ATTR */
- if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen,
- P2P_ATTR_CAPABILITY,
- (u8 *) &cap_attr,
- (uint *) &attr_contentlen)) {
- u8 grp_cap = 0;
- /* DBG_8723A( "[%s] Got P2P Capability Attr!!\n", __func__ ); */
- cap_attr = le16_to_cpu(cap_attr);
- grp_cap = (u8) ((cap_attr >> 8) & 0xff);
-
- is_GO = (grp_cap & BIT(0)) ? true : false;
-
- if (is_GO)
- DBG_8723A
- ("Got P2P Capability Attr, grp_cap"
- "= 0x%x, is_GO\n", grp_cap);
- }
-
- if (is_GO == false) {
- if (pmlmepriv->p2p_probe_resp_ie) {
- pmlmepriv->p2p_probe_resp_ie_len = 0;
- kfree(pmlmepriv->p2p_probe_resp_ie);
- pmlmepriv->p2p_probe_resp_ie = NULL;
- }
-
- pmlmepriv->p2p_probe_resp_ie =
- kmalloc(p2p_ielen, GFP_KERNEL);
- if (pmlmepriv->p2p_probe_resp_ie == NULL) {
- DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
- __func__, __LINE__);
- return -EINVAL;
- }
- memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie,
- p2p_ielen);
- pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
- } else {
- if (pmlmepriv->p2p_go_probe_resp_ie) {
- pmlmepriv->p2p_go_probe_resp_ie_len = 0;
- kfree(pmlmepriv->p2p_go_probe_resp_ie);
- pmlmepriv->p2p_go_probe_resp_ie = NULL;
- }
-
- pmlmepriv->p2p_go_probe_resp_ie =
- kmalloc(p2p_ielen, GFP_KERNEL);
- if (pmlmepriv->p2p_go_probe_resp_ie == NULL) {
- DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
- __func__, __LINE__);
- return -EINVAL;
-
- }
- memcpy(pmlmepriv->p2p_go_probe_resp_ie,
- p2p_ie, p2p_ielen);
- pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
- }
- }
-#endif /* CONFIG_8723AU_P2P */
-
- /* buf += p2p_ielen; */
- /* len -= p2p_ielen; */
-
-#ifdef CONFIG_8723AU_P2P
- if (rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) {
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_8723A("probe_resp_wfd_ielen =%d\n", wfd_ielen);
-#endif
-
- if (pmlmepriv->wfd_probe_resp_ie) {
- pmlmepriv->wfd_probe_resp_ie_len = 0;
- kfree(pmlmepriv->wfd_probe_resp_ie);
- pmlmepriv->wfd_probe_resp_ie = NULL;
- }
-
- pmlmepriv->wfd_probe_resp_ie =
- kmalloc(wfd_ielen, GFP_KERNEL);
- if (pmlmepriv->wfd_probe_resp_ie == NULL) {
- DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
- __func__, __LINE__);
- return -EINVAL;
-
- }
- rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie,
- &pmlmepriv->wfd_probe_resp_ie_len);
- }
-#endif /* CONFIG_8723AU_P2P */
}
return ret;
{
int ret = 0;
uint wps_ielen = 0;
-#ifdef CONFIG_8723AU_P2P
- u32 p2p_ielen = 0;
-#endif
-#ifdef CONFIG_DEBUG_CFG80211
DBG_8723A("%s, ielen =%d\n", __func__, len);
-#endif
- if ((rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen) && (wps_ielen > 0))
-#ifdef CONFIG_8723AU_P2P
- || (rtw_get_p2p_ie23a(buf, len, NULL, &p2p_ielen) && (p2p_ielen > 0))
-#endif
- ) {
+ if (rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen) && (wps_ielen > 0)) {
if (net) {
switch (type) {
case 0x1: /* BEACON */
.change_bss = cfg80211_rtw_change_bss,
#endif /* CONFIG_8723AU_AP_MODE */
-#ifdef CONFIG_8723AU_P2P
- .remain_on_channel = cfg80211_rtw_remain_on_channel,
- .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
-#endif
-
.mgmt_tx = cfg80211_rtw_mgmt_tx,
.mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
};
struct wireless_dev *pwdev = padapter->rtw_wdev;
struct wiphy *wiphy = pwdev->wiphy;
- rtw23a_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+ rf_type = rtl8723a_get_rf_type(padapter);
DBG_8723A("%s:rf_type =%d\n", __func__, rf_type);
BIT(NL80211_IFTYPE_ADHOC) |
#ifdef CONFIG_8723AU_AP_MODE
BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) |
-#endif
-#if defined(CONFIG_8723AU_P2P)
- BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) |
#endif
0;
#include <mlme_osdep.h>
#include <rtw_ioctl_set.h>
-void rtw_os_indicate_connect23a(struct rtw_adapter *adapter)
-{
- rtw_cfg80211_indicate_connect(adapter);
-
- netif_carrier_on(adapter->pnetdev);
-
- if (adapter->pid[2] != 0)
- rtw_signal_process(adapter->pid[2], SIGALRM);
-}
-
-void rtw_os_indicate_scan_done23a(struct rtw_adapter *padapter, bool aborted)
-{
- rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev),
- aborted);
-}
-
static struct rt_pmkid_list backupPMKIDList[NUM_PMKID_CACHE];
void rtw_reset_securitypriv23a(struct rtw_adapter *adapter)
* When the countermeasure is trigger, the driver have to
* disconnect with AP for 60 seconds.
*/
- memset(&backupPMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) *
- NUM_PMKID_CACHE);
-
memcpy(&backupPMKIDList[0], &adapter->securitypriv.PMKIDList[0],
sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
backupPMKIDIndex = adapter->securitypriv.PMKIDIndex;
rtw_reset_securitypriv23a(adapter);
}
-
-void rtw_report_sec_ie23a(struct rtw_adapter *adapter, u8 authmode, u8 *sec_ie)
-{
- uint len;
- u8 *buff, *p, i;
- union iwreq_data wrqu;
-
- RT_TRACE(_module_mlme_osdep_c_, _drv_info_,
- ("+rtw_report_sec_ie23a, authmode =%d\n", authmode));
-
- buff = NULL;
- if (authmode == _WPA_IE_ID_) {
- RT_TRACE(_module_mlme_osdep_c_, _drv_info_,
- ("rtw_report_sec_ie23a, authmode =%d\n", authmode));
-
- buff = kzalloc(IW_CUSTOM_MAX, GFP_KERNEL);
- if (!buff)
- return;
- p = buff;
-
- p += sprintf(p, "ASSOCINFO(ReqIEs =");
-
- len = sec_ie[1]+2;
- len = (len < IW_CUSTOM_MAX) ? len : IW_CUSTOM_MAX;
-
- for (i = 0; i < len; i++)
- p += sprintf(p, "%02x", sec_ie[i]);
-
- p += sprintf(p, ")");
-
- memset(&wrqu, 0, sizeof(wrqu));
-
- wrqu.data.length = p-buff;
-
- wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ?
- wrqu.data.length : IW_CUSTOM_MAX;
-
- kfree(buff);
- }
-}
-
-#ifdef CONFIG_8723AU_AP_MODE
-void rtw_indicate_sta_assoc_event23a(struct rtw_adapter *padapter,
- struct sta_info *psta)
-{
- struct sta_priv *pstapriv = &padapter->stapriv;
- union iwreq_data wrqu;
-
- if (psta == NULL)
- return;
-
- if (psta->aid > NUM_STA)
- return;
-
- if (pstapriv->sta_aid[psta->aid - 1] != psta)
- return;
-
- wrqu.addr.sa_family = ARPHRD_ETHER;
-
- memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
-
- DBG_8723A("+rtw_indicate_sta_assoc_event23a\n");
-}
-
-void rtw_indicate_sta_disassoc_event23a(struct rtw_adapter *padapter,
- struct sta_info *psta)
-{
- struct sta_priv *pstapriv = &padapter->stapriv;
- union iwreq_data wrqu;
-
- if (psta == NULL)
- return;
-
- if (psta->aid > NUM_STA)
- return;
-
- if (pstapriv->sta_aid[psta->aid - 1] != psta)
- return;
-
- wrqu.addr.sa_family = ARPHRD_ETHER;
-
- memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
-
- DBG_8723A("+rtw_indicate_sta_disassoc_event23a\n");
-}
-#endif
#include <recv_osdep.h>
#include <hal_intf.h>
#include <rtw_version.h>
-#include <ethernet.h>
#include <usb_osintf.h>
#include <linux/version.h>
static int rtw_wmm_enable = 1;/* default is set to enable the wmm. */
static int rtw_uapsd_enable;
-int rtw_ht_enable23A = 1;
+static int rtw_ht_enable = 1;
/* 0 :diable, bit(0): enable 2.4g, bit(1): enable 5g */
-int rtw_cbw40_enable23A = 3;
-int rtw_ampdu_enable23A = 1;/* for enable tx_ampdu */
+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
*/
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_enable23A, int, 0644);
-module_param(rtw_cbw40_enable23A, int, 0644);
-module_param(rtw_ampdu_enable23A, 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);
/* UAPSD */
registry_par->wmm_enable = (u8)rtw_wmm_enable;
registry_par->uapsd_enable = (u8)rtw_uapsd_enable;
- registry_par->ht_enable = (u8)rtw_ht_enable23A;
- registry_par->cbw40_enable = (u8)rtw_cbw40_enable23A;
- registry_par->ampdu_enable = (u8)rtw_ampdu_enable23A;
+ 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;
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;
+ u16 eth_type = get_unaligned_be16(ð->h_proto);
u32 priority;
u8 *pdata = skb->data;
- memcpy(ð_type, pdata + (ETH_ALEN << 1), 2);
switch (eth_type) {
- case htons(ETH_P_IP):
+ case ETH_P_IP:
piphdr = (struct iphdr *)(pdata + ETH_HLEN);
dscp = piphdr->tos & 0xfc;
priority = dscp >> 5;
return pnetdev;
}
-u32 rtw_start_drv_threads23a(struct rtw_adapter *padapter)
-{
- u32 _status = _SUCCESS;
-
- RT_TRACE(_module_os_intfs_c_, _drv_info_,
- ("+rtw_start_drv_threads23a\n"));
- padapter->cmdThread = kthread_run(rtw_cmd_thread23a, padapter,
- "RTW_CMD_THREAD");
- if (IS_ERR(padapter->cmdThread)) {
- _status = _FAIL;
- } else {
- /* wait for cmd_thread to run */
- down(&padapter->cmdpriv.terminate_cmdthread_sema);
- }
- rtw_hal_start_thread23a(padapter);
- return _status;
-}
-
-void rtw_stop_drv_threads23a(struct rtw_adapter *padapter)
-{
- RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_stop_drv_threads23a\n"));
-
- /* Below is to termindate rtw_cmd_thread23a & event_thread... */
- up(&padapter->cmdpriv.cmd_queue_sema);
- if (padapter->cmdThread)
- down(&padapter->cmdpriv.terminate_cmdthread_sema);
- rtw_hal_stop_thread23a(padapter);
-}
-
static u8 rtw_init_default_value(struct rtw_adapter *padapter)
{
struct registry_priv *pregistrypriv = &padapter->registrypriv;
/* misc. */
padapter->bReadPortCancel = false;
padapter->bWritePortCancel = false;
- padapter->bRxRSSIDisplay = 0;
padapter->bNotifyChannelChange = 0;
-#ifdef CONFIG_8723AU_P2P
- padapter->bShowGetP2PState = 1;
-#endif
return ret;
}
rtw_hal_def_value_init23a(padapter);
padapter->bReadPortCancel = false;
padapter->bWritePortCancel = false;
- padapter->bRxRSSIDisplay = 0;
pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */
padapter->xmitpriv.tx_pkts = 0;
goto exit;
}
-#ifdef CONFIG_8723AU_P2P
- rtw_init_wifidirect_timers23a(padapter);
- init_wifidirect_info23a(padapter, P2P_ROLE_DISABLE);
- reset_global_wifidirect_info23a(padapter);
- rtw_init_cfg80211_wifidirect_info(padapter);
-#ifdef CONFIG_8723AU_P2P
- if (rtw_init_wifi_display_info(padapter) == _FAIL)
- RT_TRACE(_module_os_intfs_c_, _drv_err_,
- ("\n Can't init init_wifi_display_info\n"));
-#endif
-#endif /* CONFIG_8723AU_P2P */
if (init_mlme_ext_priv23a(padapter) == _FAIL) {
RT_TRACE(_module_os_intfs_c_, _drv_err_,
del_timer_sync(&padapter->pwrctrlpriv.pwr_state_check_timer);
-#ifdef CONFIG_8723AU_P2P
- del_timer_sync(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
-#endif /* CONFIG_8723AU_P2P */
-
del_timer_sync(&padapter->mlmepriv.set_scan_deny_timer);
rtw_clear_scan_deny(padapter);
RT_TRACE(_module_os_intfs_c_, _drv_info_,
u8 rtw_free_drv_sw23a(struct rtw_adapter *padapter)
{
-#ifdef CONFIG_8723AU_P2P
- struct wifidirect_info *pwdinfo;
-#endif
-
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("==>rtw_free_drv_sw23a"));
- /* we can call rtw_p2p_enable23a here, but:
- * 1. rtw_p2p_enable23a may have IO operation
- * 2. rtw_p2p_enable23a is bundled with wext interface
- */
-#ifdef CONFIG_8723AU_P2P
- pwdinfo = &padapter->wdinfo;
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- del_timer_sync(&pwdinfo->find_phase_timer);
- del_timer_sync(&pwdinfo->restore_p2p_state_timer);
- del_timer_sync(&pwdinfo->pre_tx_scan_timer);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
- }
-#endif
-
free_mlme_ext_priv23a(&padapter->mlmeextpriv);
rtw_free_cmd_priv23a(&padapter->cmdpriv);
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("<== rtw_free_drv_sw23a\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;
- }
-
/* clear pbuddy_adapter to avoid access wrong pointer. */
if (padapter->pbuddy_adapter != NULL)
padapter->pbuddy_adapter->pbuddy_adapter = NULL;
DBG_8723A("MAC Address = "MAC_FMT"\n",
MAC_ARG(pnetdev->dev_addr));
- status = rtw_start_drv_threads23a(padapter);
- if (status == _FAIL) {
- DBG_8723A("Initialize driver software resource Failed!\n");
- goto netdev_open23a_error;
- }
-
if (init_hw_mlme_ext23a(padapter) == _FAIL) {
DBG_8723A("can't init mlme_ext_priv\n");
goto netdev_open23a_error;
void rtw_ips_dev_unload23a(struct rtw_adapter *padapter)
{
- rtw_hal_set_hwreg23a(padapter, HW_VAR_FIFO_CLEARN_UP, NULL);
+ rtl8723a_fifo_cleanup(padapter);
if (padapter->intf_stop)
padapter->intf_stop(padapter);
/* s2-3. */
rtw_free_assoc_resources23a(padapter, 1);
/* s2-4. */
- rtw_free_network_queue23a(padapter, true);
+ rtw_free_network_queue23a(padapter);
/* Close LED */
rtw_led_control(padapter, LED_CTL_POWER_OFF);
}
-#ifdef CONFIG_8723AU_P2P
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
- wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = false;
- rtw_p2p_enable23a(padapter, P2P_ROLE_DISABLE);
-#endif /* CONFIG_8723AU_P2P */
-
rtw_scan_abort23a(padapter);
/* set this at the end */
padapter->rtw_wdev->iftype = NL80211_IFTYPE_MONITOR;
#include <recv_osdep.h>
#include <linux/vmalloc.h>
-#define RT_TAG ('1178')
-
/*
* Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE23a
* @return: one of RTW_STATUS_CODE23a
return false;
}
-u64 rtw_modular6423a(u64 x, u64 y)
-{
- return do_div(x, y);
-}
-
-u64 rtw_division6423a(u64 x, u64 y)
-{
- do_div(x, y);
- return x;
-}
-
/* rtw_cbuf_full23a - test if cbuf is full
* @cbuf: pointer of struct rtw_cbuf
*
#include <recv_osdep.h>
#include <osdep_intf.h>
-#include <ethernet.h>
#include <usb_ops.h>
-/* alloc os related resource in struct recv_frame */
-int rtw_os_recv_resource_alloc23a(struct rtw_adapter *padapter,
- struct recv_frame *precvframe)
-{
- int res = _SUCCESS;
-
- precvframe->pkt = NULL;
-
- return res;
-}
-
-/* alloc os related resource in struct recv_buf */
-int rtw_os_recvbuf_resource_alloc23a(struct rtw_adapter *padapter,
- struct recv_buf *precvbuf)
-{
- int res = _SUCCESS;
-
- precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL);
- if (precvbuf->purb == NULL)
- res = _FAIL;
-
- precvbuf->pskb = NULL;
-
- return res;
-}
-
-/* free os related resource in struct recv_buf */
-int rtw_os_recvbuf_resource_free23a(struct rtw_adapter *padapter,
- struct recv_buf *precvbuf)
-{
- int ret = _SUCCESS;
-
- usb_free_urb(precvbuf->purb);
-
- if (precvbuf->pskb)
- dev_kfree_skb_any(precvbuf->pskb);
-
- return ret;
-}
-
void rtw_handle_tkip_mic_err23a(struct rtw_adapter *padapter, u8 bgroup)
{
enum nl80211_key_type key_type = 0;
wrqu.data.length = sizeof(ev);
}
-void rtw_hostapd_mlme_rx23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
-}
-
int rtw_recv_indicatepkt23a(struct rtw_adapter *padapter,
struct recv_frame *precv_frame)
{
return _FAIL;
}
-void rtw_os_read_port23a(struct rtw_adapter *padapter, struct recv_buf *precvbuf)
-{
- struct recv_priv *precvpriv = &padapter->recvpriv;
-
- /* free skb in recv_buf */
- dev_kfree_skb_any(precvbuf->pskb);
-
- precvbuf->pskb = NULL;
-
- rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, precvbuf);
-}
-
void rtw_init_recv_timer23a(struct recv_reorder_ctrl *preorder_ctrl)
{
setup_timer(&preorder_ctrl->reordering_ctrl_timer,
/* s4. */
if (!padapter->pwrctrlpriv.bInternalAutoSuspend)
- rtw_stop_drv_threads23a(padapter);
+ flush_workqueue(padapter->cmdpriv.wq);
/* s5. */
if (!padapter->bSurpriseRemoved) {
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
struct net_device *pnetdev = padapter->pnetdev;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
if ((!padapter->bup) || (padapter->bDriverStopped) ||
(padapter->bSurpriseRemoved)) {
/* s2-2. indicate disconnect to os */
/* rtw_indicate_disconnect23a(padapter); */
- {
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- _clr_fwstate_(pmlmepriv, _FW_LINKED);
+ if (check_fwstate(pmlmepriv, _FW_LINKED)) {
+ _clr_fwstate_(pmlmepriv, _FW_LINKED);
- rtw_led_control(padapter, LED_CTL_NO_LINK);
+ rtw_led_control(padapter, LED_CTL_NO_LINK);
- rtw_os_indicate_disconnect23a(padapter);
+ rtw_os_indicate_disconnect23a(padapter);
- /* donnot enqueue cmd */
- rtw_lps_ctrl_wk_cmd23a(padapter,
- LPS_CTRL_DISCONNECT, 0);
- }
+ /* donnot enqueue cmd */
+ rtw_lps_ctrl_wk_cmd23a(padapter,
+ LPS_CTRL_DISCONNECT, 0);
}
/* s2-3. */
rtw_free_assoc_resources23a(padapter, 1);
/* s2-4. */
- rtw_free_network_queue23a(padapter, true);
+ rtw_free_network_queue23a(padapter);
rtw_ips_dev_unload23a(padapter);
pwrpriv->rf_pwrstate = rf_off;
pwrpriv->bips_processing = false;
/* s2-3. */
rtw_free_assoc_resources23a(padapter, 1);
/* s2-4. */
- rtw_free_network_queue23a(padapter, true);
+ rtw_free_network_queue23a(padapter);
rtw_dev_unload(padapter);
up(&pwrpriv->lock);
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
- rtw_indicate_scan_done23a(padapter, 1);
+ rtw_cfg80211_indicate_scan_done(
+ wdev_to_priv(padapter->rtw_wdev), true);
if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
rtw_indicate_disconnect23a(padapter);
if (padapter->pid[1] != 0) {
DBG_8723A("pid[1]:%d\n", padapter->pid[1]);
- rtw_signal_process(padapter->pid[1], SIGUSR2);
+ kill_pid(find_vpid(padapter->pid[1]), SIGUSR2, 1);
}
rtw23a_roaming(padapter, NULL);
padapter->intf_start = &usb_intf_start;
padapter->intf_stop = &usb_intf_stop;
- /* step init_io_priv */
- rtw_init_io_priv23a(padapter, usb_set_intf_ops);
+ rtl8723au_set_intf_ops(padapter);
/* step read_chip_version */
rtw_hal_read_chip_version23a(padapter);
/* set mac addr */
rtw_macaddr_cfg23a(padapter->eeprompriv.mac_addr);
-#ifdef CONFIG_8723AU_P2P
- rtw_init_wifidirect_addrs23a(padapter, padapter->eeprompriv.mac_addr,
- padapter->eeprompriv.mac_addr);
-#endif
DBG_8723A("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n",
padapter->bDriverStopped, padapter->bSurpriseRemoved,
void *padapter;
};
-void usb_read_mem23a(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
+void usb_read_mem23a(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *rmem)
{
}
-void usb_write_mem23a(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
+void usb_write_mem23a(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *wmem)
{
}
-void usb_read_port_cancel23a(struct intf_hdl *pintfhdl)
+void usb_read_port_cancel23a(struct rtw_adapter *padapter)
{
struct recv_buf *precvbuf;
- struct rtw_adapter *padapter = pintfhdl->padapter;
int i;
precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf;
tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
}
-u32 usb_write_port23a(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
- struct xmit_buf *pxmitbuf)
+u32 usb_write_port23a(struct rtw_adapter *padapter, u32 addr, u32 cnt,
+ struct xmit_buf *pxmitbuf)
{
struct urb *purb = NULL;
- struct rtw_adapter *padapter = (struct rtw_adapter *)pintfhdl->padapter;
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
return ret;
}
-void usb_write_port23a_cancel(struct intf_hdl *pintfhdl)
+void usb_write_port23a_cancel(struct rtw_adapter *padapter)
{
- struct rtw_adapter *padapter = pintfhdl->padapter;
struct xmit_buf *pxmitbuf;
struct list_head *plist;
int j;
#include <xmit_osdep.h>
#include <osdep_intf.h>
-uint rtw_remainder_len23a(struct pkt_file *pfile)
-{
- return pfile->buf_len - ((unsigned long)(pfile->cur_addr) -
- (unsigned long)(pfile->buf_start));
-}
-
-void _rtw_open_pktfile23a(struct sk_buff *pktptr, struct pkt_file *pfile)
-{
- pfile->pkt = pktptr;
- pfile->buf_start = pktptr->data;
- pfile->cur_addr = pktptr->data;
- pfile->buf_len = pktptr->len;
- pfile->pkt_len = pktptr->len;
-
- pfile->cur_buffer = pfile->buf_start;
-}
-
-uint _rtw_pktfile_read23a(struct pkt_file *pfile, u8 *rmem, uint rlen)
-{
- uint len = 0;
-
- len = rtw_remainder_len23a(pfile);
- len = (rlen > len) ? len : rlen;
-
- if (rmem)
- skb_copy_bits(pfile->pkt, pfile->buf_len-pfile->pkt_len,
- rmem, len);
-
- pfile->cur_addr += len;
- pfile->pkt_len -= len;
-
- return len;
-}
-
-int rtw_endofpktfile23a(struct pkt_file *pfile)
-{
- if (pfile->pkt_len == 0)
- return true;
- return false;
-}
-
int rtw_os_xmit_resource_alloc23a(struct rtw_adapter *padapter,
struct xmit_buf *pxmitbuf, u32 alloc_sz)
{
}
-static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
+static int _rtl_init_deferred_work(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtlpriv->works.rtl_wq = create_workqueue(rtlpriv->cfg->name);
#endif
/*<delete in kernel end>*/
+ if (!rtlpriv->works.rtl_wq)
+ return -ENOMEM;
+
INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
(void *)rtl_watchdog_wq_callback);
INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
INIT_DELAYED_WORK(&rtlpriv->works.fwevt_wq,
(void *)rtl_fwevt_wq_callback);
+ return 0;
+
}
void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
INIT_LIST_HEAD(&rtlpriv->entry_list);
/* <6> init deferred work */
- _rtl_init_deferred_work(hw);
+ if (_rtl_init_deferred_work(hw))
+ return 1;
/* <7> */
#ifdef VIF_TODO
* include files
**************************************************************/
#include "halbt_precomp.h"
-#if 1
+
/**************************************************************
* Global variables, these are static variables
**************************************************************/
static struct coex_sta_8192e_2ant glcoex_sta_8192e_2ant;
static struct coex_sta_8192e_2ant *coex_sta = &glcoex_sta_8192e_2ant;
-const char *const GLBtInfoSrc8192e2Ant[]={
+static const char *const GLBtInfoSrc8192e2Ant[] = {
"BT Info[wifi fw]",
"BT Info[bt rsp]",
"BT Info[bt auto report]",
};
-u32 glcoex_ver_date_8192e_2ant = 20130902;
-u32 glcoex_ver_8192e_2ant = 0x34;
+static u32 glcoex_ver_date_8192e_2ant = 20130902;
+static u32 glcoex_ver_8192e_2ant = 0x34;
/**************************************************************
* local function proto type if needed
/**************************************************************
* local function start with halbtc8192e2ant_
**************************************************************/
-u8 halbtc8192e2ant_btrssi_state(u8 level_num, u8 rssi_thresh, u8 rssi_thresh1)
+static u8 halbtc8192e2ant_btrssi_state(u8 level_num, u8 rssi_thresh,
+ u8 rssi_thresh1)
{
- int btrssi=0;
+ int btrssi = coex_sta->bt_rssi;
u8 btrssi_state = coex_sta->pre_bt_rssi_state;
- btrssi = coex_sta->bt_rssi;
-
if (level_num == 2) {
if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
(coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
(coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
"BT Rssi pre state=LOW\n");
- if(btrssi >= (rssi_thresh +
+ if (btrssi >= (rssi_thresh +
BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
btrssi_state = BTC_RSSI_STATE_MEDIUM;
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
return btrssi_state;
}
-u8 halbtc8192e2ant_wifirssi_state(struct btc_coexist * btcoexist, u8 index,
- u8 level_num, u8 rssi_thresh, u8 rssi_thresh1)
+static u8 halbtc8192e2ant_wifirssi_state(struct btc_coexist *btcoexist,
+ u8 index, u8 level_num,
+ u8 rssi_thresh, u8 rssi_thresh1)
{
int wifirssi = 0;
u8 wifirssi_state = coex_sta->pre_wifi_rssi_state[index];
BTC_PRINT(BTC_MSG_ALGORITHM,
ALGO_WIFI_RSSI_STATE,
"wifi RSSI state stay at Low\n");
- }
- } else {
+ }
+ } else {
if (wifirssi < rssi_thresh) {
wifirssi_state = BTC_RSSI_STATE_LOW;
BTC_PRINT(BTC_MSG_ALGORITHM,
return wifirssi_state;
}
-void halbtc8192e2ant_monitor_bt_enable_disable(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_monitor_bt_enable_disable(struct btc_coexist *btcoexist)
{
- static bool pre_bt_disabled = false;
- static u32 bt_disable_cnt = 0;
+ static bool pre_bt_disabled;
+ static u32 bt_disable_cnt;
bool bt_active = true, bt_disabled = false;
/* This function check if bt is disabled */
}
}
-u32 halbtc8192e2ant_decidera_mask(struct btc_coexist *btcoexist,
+static u32 halbtc8192e2ant_decidera_mask(struct btc_coexist *btcoexist,
u8 sstype, u32 ra_masktype)
{
u32 disra_mask = 0x0;
disra_mask = 0xfff00000;/* disable 2ss */
break;
case 1: /* disable cck 1/2 */
- if(sstype == 2)
+ if (sstype == 2)
disra_mask = 0x00000003;/* enable 2ss */
else
disra_mask = 0xfff00003;/* disable 2ss */
break;
case 2: /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 */
- if(sstype == 2)
+ if (sstype == 2)
disra_mask = 0x0001f1f7;/* enable 2ss */
else
disra_mask = 0xfff1f1f7;/* disable 2ss */
return disra_mask;
}
-void halbtc8192e2ant_Updatera_mask(struct btc_coexist *btcoexist,
- bool force_exec, u32 dis_ratemask)
+static void halbtc8192e2ant_Updatera_mask(struct btc_coexist *btcoexist,
+ bool force_exec, u32 dis_ratemask)
{
coex_dm->curra_mask = dis_ratemask;
coex_dm->prera_mask = coex_dm->curra_mask;
}
-void halbtc8192e2ant_autorate_fallback_retry(struct btc_coexist *btcoexist,
- bool force_exec, u8 type)
+static void halbtc8192e2ant_autorate_fallback_retry(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
{
bool wifi_under_bmode = false;
coex_dm->pre_arfrtype = coex_dm->cur_arfrtype;
}
-void halbtc8192e2ant_retrylimit(struct btc_coexist *btcoexist,
- bool force_exec, u8 type)
+static void halbtc8192e2ant_retrylimit(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
{
coex_dm->cur_retrylimit_type = type;
if (force_exec || (coex_dm->pre_retrylimit_type !=
coex_dm->cur_retrylimit_type)) {
switch (coex_dm->cur_retrylimit_type) {
- case 0: /* normal mode */
- btcoexist->btc_write_2byte(btcoexist, 0x42a,
- coex_dm->backup_retrylimit);
- break;
- case 1: /* retry limit=8 */
- btcoexist->btc_write_2byte(btcoexist, 0x42a,
- 0x0808);
- break;
- default:
- break;
+ case 0: /* normal mode */
+ btcoexist->btc_write_2byte(btcoexist, 0x42a,
+ coex_dm->backup_retrylimit);
+ break;
+ case 1: /* retry limit=8 */
+ btcoexist->btc_write_2byte(btcoexist, 0x42a,
+ 0x0808);
+ break;
+ default:
+ break;
}
}
coex_dm->pre_retrylimit_type = coex_dm->cur_retrylimit_type;
}
-void halbtc8192e2ant_ampdu_maxtime(struct btc_coexist *btcoexist,
- bool force_exec, u8 type)
+static void halbtc8192e2ant_ampdu_maxtime(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
{
coex_dm->cur_ampdutime_type = type;
coex_dm->pre_ampdutime_type = coex_dm->cur_ampdutime_type;
}
-void halbtc8192e2ant_limited_tx(struct btc_coexist *btcoexist,
- bool force_exec, u8 ra_masktype, u8 arfr_type,
- u8 retrylimit_type, u8 ampdutime_type)
+static void halbtc8192e2ant_limited_tx(struct btc_coexist *btcoexist,
+ bool force_exec, u8 ra_masktype,
+ u8 arfr_type, u8 retrylimit_type,
+ u8 ampdutime_type)
{
u32 disra_mask = 0x0;
halbtc8192e2ant_ampdu_maxtime(btcoexist, force_exec, ampdutime_type);
}
-void halbtc8192e2ant_limited_rx(struct btc_coexist *btcoexist,
- bool force_exec, bool rej_ap_agg_pkt,
- bool b_bt_ctrl_agg_buf_size,
- u8 agg_buf_size)
+static void halbtc8192e2ant_limited_rx(struct btc_coexist *btcoexist,
+ bool force_exec, bool rej_ap_agg_pkt,
+ bool b_bt_ctrl_agg_buf_size,
+ u8 agg_buf_size)
{
bool reject_rx_agg = rej_ap_agg_pkt;
bool bt_ctrl_rx_agg_size = b_bt_ctrl_agg_buf_size;
}
-void halbtc8192e2ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
{
u32 reg_hp_txrx, reg_lp_txrx, u32tmp;
u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0;
btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
}
-void halbtc8192e2ant_querybt_info(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_querybt_info(struct btc_coexist *btcoexist)
{
- u8 h2c_parameter[1] ={0};
+ u8 h2c_parameter[1] = {0};
coex_sta->c2h_bt_info_req_sent = true;
btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
}
-bool halbtc8192e2ant_iswifi_status_changed(struct btc_coexist *btcoexist)
-{
- static bool pre_wifi_busy = false;
- static bool pre_under_4way = false, pre_bt_hson = false;
- bool wifi_busy = false, under_4way = false, bt_hson = false;
- bool wifi_connected = false;
-
- btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
- &wifi_connected);
- btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
- btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson);
- btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
- &under_4way);
-
- if (wifi_connected) {
- if (wifi_busy != pre_wifi_busy) {
- pre_wifi_busy = wifi_busy;
- return true;
- }
- if (under_4way != pre_under_4way) {
- pre_under_4way = under_4way;
- return true;
- }
- if (bt_hson != pre_bt_hson) {
- pre_bt_hson = bt_hson;
- return true;
- }
- }
-
- return false;
-}
-
-void halbtc8192e2ant_update_btlink_info(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_update_btlink_info(struct btc_coexist *btcoexist)
{
struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
bool bt_hson = false;
bt_link_info->hid_only = false;
}
-u8 halbtc8192e2ant_action_algorithm(struct btc_coexist *btcoexist)
+static u8 halbtc8192e2ant_action_algorithm(struct btc_coexist *btcoexist)
{
struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
struct btc_stack_info *stack_info = &btcoexist->stack_info;
- bool bt_hson=false;
+ bool bt_hson = false;
u8 algorithm = BT_8192E_2ANT_COEX_ALGO_UNDEFINED;
u8 numOfDiffProfile = 0;
return algorithm;
}
-void halbtc8192e2ant_setfw_dac_swinglevel(struct btc_coexist *btcoexist,
- u8 dac_swinglvl)
+static void halbtc8192e2ant_setfw_dac_swinglevel(struct btc_coexist *btcoexist,
+ u8 dac_swinglvl)
{
- u8 h2c_parameter[1] ={0};
+ u8 h2c_parameter[1] = {0};
/* There are several type of dacswing
* 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 */
btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter);
}
-void halbtc8192e2ant_set_fwdec_btpwr(struct btc_coexist *btcoexist,
- u8 dec_btpwr_lvl)
+static void halbtc8192e2ant_set_fwdec_btpwr(struct btc_coexist *btcoexist,
+ u8 dec_btpwr_lvl)
{
- u8 h2c_parameter[1] ={0};
+ u8 h2c_parameter[1] = {0};
h2c_parameter[0] = dec_btpwr_lvl;
btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter);
}
-void halbtc8192e2ant_dec_btpwr(struct btc_coexist *btcoexist,
- bool force_exec, u8 dec_btpwr_lvl)
+static void halbtc8192e2ant_dec_btpwr(struct btc_coexist *btcoexist,
+ bool force_exec, u8 dec_btpwr_lvl)
{
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
"[BTCoex], %s Dec BT power level = %d\n",
- (force_exec? "force to":""), dec_btpwr_lvl);
+ (force_exec ? "force to":""), dec_btpwr_lvl);
coex_dm->cur_dec_bt_pwr = dec_btpwr_lvl;
if (!force_exec) {
coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr;
}
-void halbtc8192e2ant_set_bt_autoreport(struct btc_coexist *btcoexist,
- bool enable_autoreport)
+static void halbtc8192e2ant_set_bt_autoreport(struct btc_coexist *btcoexist,
+ bool enable_autoreport)
{
- u8 h2c_parameter[1] ={0};
+ u8 h2c_parameter[1] = {0};
h2c_parameter[0] = 0;
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
"[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n",
- (enable_autoreport? "Enabled!!":"Disabled!!"),
+ (enable_autoreport ? "Enabled!!":"Disabled!!"),
h2c_parameter[0]);
btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter);
}
-void halbtc8192e2ant_bt_autoreport(struct btc_coexist *btcoexist,
- bool force_exec, bool enable_autoreport)
+static void halbtc8192e2ant_bt_autoreport(struct btc_coexist *btcoexist,
+ bool force_exec,
+ bool enable_autoreport)
{
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
"[BTCoex], %s BT Auto report = %s\n",
- (force_exec? "force to":""),
- ((enable_autoreport)? "Enabled":"Disabled"));
+ (force_exec ? "force to":""),
+ ((enable_autoreport) ? "Enabled":"Disabled"));
coex_dm->cur_bt_auto_report = enable_autoreport;
if (!force_exec) {
coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report;
}
-void halbtc8192e2ant_fw_dac_swinglvl(struct btc_coexist *btcoexist,
- bool force_exec, u8 fw_dac_swinglvl)
+static void halbtc8192e2ant_fw_dac_swinglvl(struct btc_coexist *btcoexist,
+ bool force_exec, u8 fw_dac_swinglvl)
{
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
"[BTCoex], %s set FW Dac Swing level = %d\n",
- (force_exec? "force to":""), fw_dac_swinglvl);
+ (force_exec ? "force to":""), fw_dac_swinglvl);
coex_dm->cur_fw_dac_swing_lvl = fw_dac_swinglvl;
if (!force_exec) {
coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl;
}
-void halbtc8192e2ant_set_sw_rf_rx_lpf_corner(struct btc_coexist *btcoexist,
- bool rx_rf_shrink_on)
+static void halbtc8192e2ant_set_sw_rf_rx_lpf_corner(struct btc_coexist *btcoexist,
+ bool rx_rf_shrink_on)
{
if (rx_rf_shrink_on) {
/* Shrink RF Rx LPF corner */
}
}
-void halbtc8192e2ant_rf_shrink(struct btc_coexist *btcoexist,
- bool force_exec, bool rx_rf_shrink_on)
+static void halbtc8192e2ant_rf_shrink(struct btc_coexist *btcoexist,
+ bool force_exec, bool rx_rf_shrink_on)
{
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
"[BTCoex], %s turn Rx RF Shrink = %s\n",
- (force_exec? "force to":""), ((rx_rf_shrink_on)? "ON":"OFF"));
+ (force_exec ? "force to":""), ((rx_rf_shrink_on) ? "ON":"OFF"));
coex_dm->cur_rf_rx_lpf_shrink = rx_rf_shrink_on;
if (!force_exec) {
coex_dm->pre_rf_rx_lpf_shrink = coex_dm->cur_rf_rx_lpf_shrink;
}
-void halbtc8192e2ant_set_sw_penalty_tx_rateadaptive(
- struct btc_coexist *btcoexist,
- bool low_penalty_ra)
-{
- u8 h2c_parameter[6] ={0};
-
- h2c_parameter[0] = 0x6; /* opCode, 0x6= Retry_Penalty */
-
- if (low_penalty_ra) {
- h2c_parameter[1] |= BIT0;
- /* normal rate except MCS7/6/5, OFDM54/48/36 */
- h2c_parameter[2] = 0x00;
- h2c_parameter[3] = 0xf7; /* MCS7 or OFDM54 */
- h2c_parameter[4] = 0xf8; /* MCS6 or OFDM48 */
- h2c_parameter[5] = 0xf9; /* MCS5 or OFDM36 */
- }
-
- BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
- "[BTCoex], set WiFi Low-Penalty Retry: %s",
- (low_penalty_ra? "ON!!":"OFF!!"));
-
- btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter);
-}
-
-void halbtc8192e2ant_low_penalty_ra(struct btc_coexist *btcoexist,
- bool force_exec, bool low_penalty_ra)
-{
- BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
- "[BTCoex], %s turn LowPenaltyRA = %s\n",
- (force_exec? "force to":""), ((low_penalty_ra)? "ON":"OFF"));
- coex_dm->cur_low_penalty_ra = low_penalty_ra;
-
- if (!force_exec) {
- BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
- "[BTCoex] bPreLowPenaltyRa=%d, bCurLowPenaltyRa=%d\n",
- coex_dm->pre_low_penalty_ra,
- coex_dm->cur_low_penalty_ra);
-
- if (coex_dm->pre_low_penalty_ra ==
- coex_dm->cur_low_penalty_ra)
- return;
- }
- halbtc8192e2ant_set_sw_penalty_tx_rateadaptive(btcoexist,
- coex_dm->cur_low_penalty_ra);
-
- coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
-}
-
-void halbtc8192e2ant_set_dac_swingreg(struct btc_coexist *btcoexist,
- u32 level)
+static void halbtc8192e2ant_set_dac_swingreg(struct btc_coexist *btcoexist,
+ u32 level)
{
u8 val = (u8)level;
btcoexist->btc_write_1byte_bitmask(btcoexist, 0x883, 0x3e, val);
}
-void halbtc8192e2ant_setsw_fulltime_dacswing(struct btc_coexist *btcoexist,
- bool sw_dac_swingon,
- u32 sw_dac_swinglvl)
+static void halbtc8192e2ant_setsw_fulltime_dacswing(struct btc_coexist *btcoexist,
+ bool sw_dac_swingon,
+ u32 sw_dac_swinglvl)
{
if (sw_dac_swingon)
halbtc8192e2ant_set_dac_swingreg(btcoexist, sw_dac_swinglvl);
halbtc8192e2ant_set_dac_swingreg(btcoexist, 0x18);
}
-
-void halbtc8192e2ant_DacSwing(struct btc_coexist *btcoexist,
- bool force_exec, bool dac_swingon,
- u32 dac_swinglvl)
+static void halbtc8192e2ant_DacSwing(struct btc_coexist *btcoexist,
+ bool force_exec, bool dac_swingon,
+ u32 dac_swinglvl)
{
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
"[BTCoex], %s turn DacSwing=%s, dac_swinglvl=0x%x\n",
- (force_exec? "force to":""),
- ((dac_swingon)? "ON":"OFF"), dac_swinglvl);
+ (force_exec ? "force to":""),
+ ((dac_swingon) ? "ON":"OFF"), dac_swinglvl);
coex_dm->cur_dac_swing_on = dac_swingon;
coex_dm->cur_dac_swing_lvl = dac_swinglvl;
coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl;
}
-void halbtc8192e2ant_set_adc_backoff(struct btc_coexist *btcoexist,
- bool adc_backoff)
-{
- if(adc_backoff)
- {
- BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
- "[BTCoex], BB BackOff Level On!\n");
- btcoexist->btc_write_1byte_bitmask(btcoexist, 0xc05, 0x30, 0x3);
- }
- else
- {
- BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
- "[BTCoex], BB BackOff Level Off!\n");
- btcoexist->btc_write_1byte_bitmask(btcoexist, 0xc05, 0x30, 0x1);
- }
-}
-
-void halbtc8192e2ant_adc_backoff(struct btc_coexist *btcoexist,
- bool force_exec, bool adc_backoff)
-{
- BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
- "[BTCoex], %s turn AdcBackOff = %s\n",
- (force_exec? "force to":""), ((adc_backoff)? "ON":"OFF"));
- coex_dm->cur_adc_back_off = adc_backoff;
-
- if (!force_exec) {
- BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
- "[BTCoex], bPreAdcBackOff=%d, bCurAdcBackOff=%d\n",
- coex_dm->pre_adc_back_off, coex_dm->cur_adc_back_off);
-
- if (coex_dm->pre_adc_back_off == coex_dm->cur_adc_back_off)
- return;
- }
- halbtc8192e2ant_set_adc_backoff(btcoexist, coex_dm->cur_adc_back_off);
-
- coex_dm->pre_adc_back_off = coex_dm->cur_adc_back_off;
-}
-
-void halbtc8192e2ant_set_agc_table(struct btc_coexist *btcoexist,
- bool agc_table_en)
+static void halbtc8192e2ant_set_agc_table(struct btc_coexist *btcoexist,
+ bool agc_table_en)
{
/* BB AGC Gain Table */
} else {
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
"[BTCoex], BB Agc Table Off!\n");
- btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xaa1A0001);
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xaa1A0001);
btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa91B0001);
btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa81C0001);
btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa71D0001);
}
}
-void halbtc8192e2ant_AgcTable(struct btc_coexist *btcoexist,
- bool force_exec, bool agc_table_en)
+static void halbtc8192e2ant_AgcTable(struct btc_coexist *btcoexist,
+ bool force_exec, bool agc_table_en)
{
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
"[BTCoex], %s %s Agc Table\n",
- (force_exec? "force to":""),
- ((agc_table_en)? "Enable":"Disable"));
+ (force_exec ? "force to":""),
+ ((agc_table_en) ? "Enable":"Disable"));
coex_dm->cur_agc_table_en = agc_table_en;
if (!force_exec) {
coex_dm->pre_agc_table_en = coex_dm->cur_agc_table_en;
}
-void halbtc8192e2ant_set_coex_table(struct btc_coexist *btcoexist,
- u32 val0x6c0, u32 val0x6c4,
- u32 val0x6c8, u8 val0x6cc)
+static void halbtc8192e2ant_set_coex_table(struct btc_coexist *btcoexist,
+ u32 val0x6c0, u32 val0x6c4,
+ u32 val0x6c8, u8 val0x6cc)
{
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
"[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0);
btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
}
-void halbtc8192e2ant_coex_table(struct btc_coexist *btcoexist, bool force_exec,
- u32 val0x6c0, u32 val0x6c4,
- u32 val0x6c8, u8 val0x6cc)
+static void halbtc8192e2ant_coex_table(struct btc_coexist *btcoexist,
+ bool force_exec,
+ u32 val0x6c0, u32 val0x6c4,
+ u32 val0x6c8, u8 val0x6cc)
{
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
"[BTCoex], %s write Coex Table 0x6c0=0x%x, ",
- (force_exec? "force to":""), val0x6c0);
+ (force_exec ? "force to":""), val0x6c0);
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
"0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n",
val0x6c4, val0x6c8, val0x6cc);
"preVal0x6c8=0x%x, preVal0x6cc=0x%x !!\n",
coex_dm->pre_val0x6c8, coex_dm->pre_val0x6cc);
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
- "[BTCoex], curVal0x6c0=0x%x, curVal0x6c4=0x%x, \n",
+ "[BTCoex], curVal0x6c0=0x%x, curVal0x6c4=0x%x,\n",
coex_dm->cur_val0x6c0, coex_dm->cur_val0x6c4);
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
"curVal0x6c8=0x%x, curVal0x6cc=0x%x !!\n",
coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc;
}
-void halbtc8192e2ant_coex_table_with_type(struct btc_coexist *btcoexist,
- bool force_exec, u8 type)
+static void halbtc8192e2ant_coex_table_with_type(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
{
switch (type) {
case 0:
}
}
-void halbtc8192e2ant_set_fw_ignore_wlanact(struct btc_coexist *btcoexist,
- bool enable)
+static void halbtc8192e2ant_set_fw_ignore_wlanact(struct btc_coexist *btcoexist,
+ bool enable)
{
- u8 h2c_parameter[1] ={0};
+ u8 h2c_parameter[1] = {0};
if (enable)
h2c_parameter[0] |= BIT0; /* function enable */
btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
}
-void halbtc8192e2ant_IgnoreWlanAct(struct btc_coexist *btcoexist,
- bool force_exec, bool enable)
+static void halbtc8192e2ant_IgnoreWlanAct(struct btc_coexist *btcoexist,
+ bool force_exec, bool enable)
{
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
"[BTCoex], %s turn Ignore WlanAct %s\n",
- (force_exec? "force to":""), (enable? "ON":"OFF"));
+ (force_exec ? "force to":""), (enable ? "ON":"OFF"));
coex_dm->cur_ignore_wlan_act = enable;
if (!force_exec) {
coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
}
-void halbtc8192e2ant_SetFwPstdma(struct btc_coexist *btcoexist, u8 byte1,
- u8 byte2, u8 byte3, u8 byte4, u8 byte5)
+static void halbtc8192e2ant_SetFwPstdma(struct btc_coexist *btcoexist, u8 byte1,
+ u8 byte2, u8 byte3, u8 byte4, u8 byte5)
{
- u8 h2c_parameter[5] ={0};
+ u8 h2c_parameter[5] = {0};
h2c_parameter[0] = byte1;
h2c_parameter[1] = byte2;
btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
}
-void halbtc8192e2ant_sw_mechanism1(struct btc_coexist *btcoexist,
- bool shrink_rx_lpf, bool low_penalty_ra,
- bool limited_dig, bool btlan_constrain)
+static void halbtc8192e2ant_sw_mechanism1(struct btc_coexist *btcoexist,
+ bool shrink_rx_lpf,
+ bool low_penalty_ra,
+ bool limited_dig,
+ bool btlan_constrain)
{
halbtc8192e2ant_rf_shrink(btcoexist, NORMAL_EXEC, shrink_rx_lpf);
}
-void halbtc8192e2ant_sw_mechanism2(struct btc_coexist *btcoexist,
- bool agc_table_shift, bool adc_backoff,
- bool sw_dac_swing, u32 dac_swinglvl)
+static void halbtc8192e2ant_sw_mechanism2(struct btc_coexist *btcoexist,
+ bool agc_table_shift,
+ bool adc_backoff,
+ bool sw_dac_swing,
+ u32 dac_swinglvl)
{
halbtc8192e2ant_AgcTable(btcoexist, NORMAL_EXEC, agc_table_shift);
halbtc8192e2ant_DacSwing(btcoexist, NORMAL_EXEC, sw_dac_swing,
dac_swinglvl);
}
-void halbtc8192e2ant_ps_tdma(struct btc_coexist *btcoexist,
- bool force_exec, bool turn_on, u8 type)
+static void halbtc8192e2ant_ps_tdma(struct btc_coexist *btcoexist,
+ bool force_exec, bool turn_on, u8 type)
{
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
"[BTCoex], %s turn %s PS TDMA, type=%d\n",
- (force_exec? "force to":""), (turn_on? "ON":"OFF"), type);
+ (force_exec ? "force to":""), (turn_on ? "ON":"OFF"), type);
coex_dm->cur_ps_tdma_on = turn_on;
coex_dm->cur_ps_tdma = type;
coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
}
-void halbtc8192e2ant_set_switch_sstype(struct btc_coexist *btcoexist, u8 sstype)
+static void halbtc8192e2ant_set_switch_sstype(struct btc_coexist *btcoexist,
+ u8 sstype)
{
u8 mimops = BTC_MIMO_PS_DYNAMIC;
u32 disra_mask = 0x0;
/* switch cck patch */
btcoexist->btc_write_1byte_bitmask(btcoexist, 0xe77, 0x4, 0x1);
btcoexist->btc_write_1byte(btcoexist, 0xa07, 0x81);
- mimops=BTC_MIMO_PS_STATIC;
+ mimops = BTC_MIMO_PS_STATIC;
} else if (sstype == 2) {
halbtc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
btcoexist->btc_write_1byte(btcoexist, 0xc04, 0x33);
btcoexist->btc_write_4byte(btcoexist, 0x90c, 0x81121313);
btcoexist->btc_write_1byte_bitmask(btcoexist, 0xe77, 0x4, 0x0);
btcoexist->btc_write_1byte(btcoexist, 0xa07, 0x41);
- mimops=BTC_MIMO_PS_DYNAMIC;
+ mimops = BTC_MIMO_PS_DYNAMIC;
}
/* set rx 1ss or 2ss */
btcoexist->btc_set(btcoexist, BTC_SET_ACT_SEND_MIMO_PS, &mimops);
}
-void halbtc8192e2ant_switch_sstype(struct btc_coexist *btcoexist,
+static void halbtc8192e2ant_switch_sstype(struct btc_coexist *btcoexist,
bool force_exec, u8 new_sstype)
{
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
"[BTCoex], %s Switch SS Type = %d\n",
- (force_exec? "force to":""), new_sstype);
+ (force_exec ? "force to":""), new_sstype);
coex_dm->cur_sstype = new_sstype;
if (!force_exec) {
coex_dm->pre_sstype = coex_dm->cur_sstype;
}
-void halbtc8192e2ant_coex_alloff(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_coex_alloff(struct btc_coexist *btcoexist)
{
/* fw all off */
halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
}
-void halbtc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist)
{
/* force to reset coex mechanism */
halbtc8192e2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
}
-void halbtc8192e2ant_action_bt_inquiry(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_action_bt_inquiry(struct btc_coexist *btcoexist)
{
bool low_pwr_disable = true;
halbtc8192e2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
}
-bool halbtc8192e2ant_is_common_action(struct btc_coexist *btcoexist)
+static bool halbtc8192e2ant_is_common_action(struct btc_coexist *btcoexist)
{
struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
bool common = false, wifi_connected = false, wifi_busy = false;
halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
- halbtc8192e2ant_sw_mechanism1(btcoexist, false, false, false,
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false, false,
false);
halbtc8192e2ant_sw_mechanism2(btcoexist, false, false, false,
0x18);
return common;
}
-void halbtc8192e2ant_tdma_duration_adjust(struct btc_coexist *btcoexist,
- bool sco_hid, bool tx_pause,
- u8 max_interval)
+static void halbtc8192e2ant_tdma_duration_adjust(struct btc_coexist *btcoexist,
+ bool sco_hid, bool tx_pause,
+ u8 max_interval)
{
static int up, dn, m, n, wait_cnt;
/* 0: no change, +1: increase WiFi duration,
up = 0;
dn = 0;
m = 1;
- n= 3;
+ n = 3;
result = 0;
wait_cnt = 0;
} else {
12;
}
} else if (result == 1) {
- if (coex_dm->cur_ps_tdma == 4) {
+ if (coex_dm->cur_ps_tdma == 4) {
halbtc8192e2ant_ps_tdma(
btcoexist,
NORMAL_EXEC,
true, 2);
coex_dm->ps_tdma_du_adj_type =
2;
- } else if(coex_dm->cur_ps_tdma == 12) {
+ } else if (coex_dm->cur_ps_tdma == 12) {
halbtc8192e2ant_ps_tdma(
btcoexist,
NORMAL_EXEC,
true, 11);
coex_dm->ps_tdma_du_adj_type =
11;
- } else if(coex_dm->cur_ps_tdma == 11) {
+ } else if (coex_dm->cur_ps_tdma == 11) {
halbtc8192e2ant_ps_tdma(
btcoexist,
NORMAL_EXEC,
true, 10);
coex_dm->ps_tdma_du_adj_type =
10;
- } else if(coex_dm->cur_ps_tdma == 10) {
+ } else if (coex_dm->cur_ps_tdma == 10) {
halbtc8192e2ant_ps_tdma(
btcoexist,
NORMAL_EXEC,
if (coex_dm->cur_ps_tdma != coex_dm->ps_tdma_du_adj_type) {
bool scan = false, link = false, roam = false;
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
- "[BTCoex], PsTdma type dismatch!!!, " );
+ "[BTCoex], PsTdma type dismatch!!!, ");
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
"curPsTdma=%d, recordPsTdma=%d\n",
coex_dm->cur_ps_tdma, coex_dm->ps_tdma_du_adj_type);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
- if ( !scan && !link && !roam)
+ if (!scan && !link && !roam)
halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
true,
coex_dm->ps_tdma_du_adj_type);
}
/* SCO only or SCO+PAN(HS) */
-void halbtc8192e2ant_action_sco(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_action_sco(struct btc_coexist *btcoexist)
{
u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_STAY_LOW;
u32 wifi_bw;
}
}
-void halbtc8192e2ant_action_sco_pan(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_action_sco_pan(struct btc_coexist *btcoexist)
{
u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_STAY_LOW;
u32 wifi_bw;
}
}
-void halbtc8192e2ant_action_hid(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_action_hid(struct btc_coexist *btcoexist)
{
- u8 wifirssi_state, btrssi_state=BTC_RSSI_STATE_HIGH;
+ u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
u32 wifi_bw;
wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
false, 0x18);
} else {
- halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
false, false);
halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
false, 0x18);
false, false);
halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
false, 0x18);
- } else {
- halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
false, false);
halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
false, 0x18);
}
/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
-void halbtc8192e2ant_action_a2dp(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_action_a2dp(struct btc_coexist *btcoexist)
{
u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
u32 wifi_bw;
if (BTC_WIFI_BW_HT40 == wifi_bw) {
if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
(wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
- halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
false, false);
halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
false, 0x18);
}
}
-void halbtc8192e2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
{
u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
u32 wifi_bw;
if (BTC_WIFI_BW_HT40 == wifi_bw) {
if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
(wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
- halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
false, false);
halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
true, 0x6);
}
}
-void halbtc8192e2ant_action_pan_edr(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_action_pan_edr(struct btc_coexist *btcoexist)
{
u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
u32 wifi_bw;
}
/* PAN(HS) only */
-void halbtc8192e2ant_action_pan_hs(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_action_pan_hs(struct btc_coexist *btcoexist)
{
u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
u32 wifi_bw;
}
/* PAN(EDR)+A2DP */
-void halbtc8192e2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
{
- u8 wifirssi_state, btrssi_state=BTC_RSSI_STATE_HIGH;
+ u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
u32 wifi_bw;
wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
}
}
-void halbtc8192e2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
{
u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
u32 wifi_bw;
if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
(btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
- halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
} else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
(btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
- halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
} else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
(btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
- halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
}
/* sw mechanism */
}
/* HID+A2DP+PAN(EDR) */
-void halbtc8192e2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
{
u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
u32 wifi_bw;
}
}
-void halbtc8192e2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
{
u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
u32 wifi_bw;
halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, true, 2);
} else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
- (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
+ (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 2);
} else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
}
}
-void halbtc8192e2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
+static void halbtc8192e2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
{
u8 algorithm = 0;
coex_dm->cur_algorithm = algorithm;
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
- "[BTCoex], Algorithm = %d \n", coex_dm->cur_algorithm);
+ "[BTCoex], Algorithm = %d\n", coex_dm->cur_algorithm);
if (halbtc8192e2ant_is_common_action(btcoexist)) {
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
}
}
-void halbtc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist, bool backup)
+static void halbtc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist,
+ bool backup)
{
u16 u16tmp = 0;
u8 u8tmp = 0;
void ex_halbtc8192e2ant_display_coex_info(struct btc_coexist *btcoexist)
{
struct btc_board_info *board_info = &btcoexist->board_info;
- struct btc_stack_info*stack_info = &btcoexist->stack_info;
+ struct btc_stack_info *stack_info = &btcoexist->stack_info;
u8 *cli_buf = btcoexist->cli_buf;
u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0;
u16 u16tmp[4];
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ",
"Wifi status", (wifi_under_5g ? "5G" : "2.4G"),
((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
- (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
+ (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
((!wifi_busy) ? "idle" :
- ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
+ ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
"uplink" : "downlink")));
CL_PRINTF(cli_buf);
(bt_info_ext&BIT0) ? "Basic rate" : "EDR rate");
CL_PRINTF(cli_buf);
- for (i=0; i<BT_INFO_SRC_8192E_2ANT_MAX; i++) {
+ for (i = 0; i < BT_INFO_SRC_8192E_2ANT_MAX; i++) {
if (coex_sta->bt_info_c2h_cnt[i]) {
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
"\r\n %-35s = %02x %02x %02x %02x ",
"0x774(lp rx[31:16]/tx[15:0])",
coex_sta->low_priority_rx, coex_sta->low_priority_tx);
CL_PRINTF(cli_buf);
-#if(BT_AUTO_REPORT_ONLY_8192E_2ANT == 1)
- halbtc8192e2ant_monitor_bt_ctr(btcoexist);
-#endif
btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
}
if (BTC_SCAN_START == type)
BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
"[BTCoex], SCAN START notify\n");
- else if(BTC_SCAN_FINISH == type)
+ else if (BTC_SCAN_FINISH == type)
BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
"[BTCoex], SCAN FINISH notify\n");
}
if (BTC_ASSOCIATE_START == type)
BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
"[BTCoex], CONNECT START notify\n");
- else if(BTC_ASSOCIATE_FINISH == type)
+ else if (BTC_ASSOCIATE_FINISH == type)
BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
"[BTCoex], CONNECT FINISH notify\n");
}
void ex_halbtc8192e2ant_media_status_notify(struct btc_coexist *btcoexist,
u8 type)
{
- u8 h2c_parameter[3] ={0};
+ u8 h2c_parameter[3] = {0};
u32 wifi_bw;
u8 wifi_center_chnl;
u8 type)
{
if (type == BTC_PACKET_DHCP)
- BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
"[BTCoex], DHCP Packet notify\n");
- }
+}
void ex_halbtc8192e2ant_bt_info_notify(struct btc_coexist *btcoexist,
- u8 *tmp_buf, u8 length )
+ u8 *tmp_buf, u8 length)
{
u8 bt_info = 0;
u8 i, rspSource = 0;
* do nothing here. */
}
-#if(BT_AUTO_REPORT_ONLY_8192E_2ANT == 0)
if ((coex_sta->bt_info_ext & BIT4)) {
/* BT auto report already enabled, do nothing */
} else {
halbtc8192e2ant_bt_autoreport(btcoexist, FORCE_EXEC,
true);
}
-#endif
}
/* check BIT2 first ==> check if bt is under inquiry or page scan */
- if(bt_info & BT_INFO_8192E_2ANT_B_INQ_PAGE)
+ if (bt_info & BT_INFO_8192E_2ANT_B_INQ_PAGE)
coex_sta->c2h_bt_inquiry_page = true;
else
coex_sta->c2h_bt_inquiry_page = false;
{
if (BTC_STACK_OP_INQ_PAGE_PAIR_START == type)
BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
- "[BTCoex] StackOP Inquiry/page/pair start notify\n");
- else if(BTC_STACK_OP_INQ_PAGE_PAIR_FINISH == type)
+ "[BTCoex] StackOP Inquiry/page/pair start notify\n");
+ else if (BTC_STACK_OP_INQ_PAGE_PAIR_FINISH == type)
BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
- "[BTCoex] StackOP Inquiry/page/pair finish notify\n");
+ "[BTCoex] StackOP Inquiry/page/pair finish notify\n");
}
void ex_halbtc8192e2ant_halt_notify(struct btc_coexist *btcoexist)
void ex_halbtc8192e2ant_periodical(struct btc_coexist *btcoexist)
{
- static u8 dis_ver_info_cnt = 0;
+ static u8 dis_ver_info_cnt;
u32 fw_ver = 0, bt_patch_ver = 0;
- struct btc_board_info *board_info=&btcoexist->board_info;
- struct btc_stack_info *stack_info=&btcoexist->stack_info;
+ struct btc_board_info *board_info = &btcoexist->board_info;
+ struct btc_stack_info *stack_info = &btcoexist->stack_info;
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
"=======================Periodical=======================\n");
"************************************************\n");
}
-#if(BT_AUTO_REPORT_ONLY_8192E_2ANT == 0)
halbtc8192e2ant_querybt_info(btcoexist);
halbtc8192e2ant_monitor_bt_ctr(btcoexist);
halbtc8192e2ant_monitor_bt_enable_disable(btcoexist);
-#else
- if (halbtc8192e2ant_iswifi_status_changed(btcoexist) ||
- coex_dm->auto_tdma_adjust)
- halbtc8192e2ant_run_coexist_mechanism(btcoexist);
-#endif
}
-
-#endif
-
/*****************************************************************
* The following is for 8192E 2Ant BT Co-exist definition
*****************************************************************/
-#define BT_AUTO_REPORT_ONLY_8192E_2ANT 0
-
#define BT_INFO_8192E_2ANT_B_FTP BIT7
#define BT_INFO_8192E_2ANT_B_A2DP BIT6
#define BT_INFO_8192E_2ANT_B_HID BIT5
/*shared mem start */
rtlpriv->io.pci_mem_start =
- (unsigned long)pci_iomap(pdev,
+ pci_iomap(pdev,
rtlpriv->cfg->bar_id, pmem_len);
- if (rtlpriv->io.pci_mem_start == 0) {
+ if (rtlpriv->io.pci_mem_start == NULL) {
RT_ASSERT(false, ("Can't map PCI mem\n"));
goto fail2;
}
RT_TRACE(COMP_INIT, DBG_DMESG,
("mem mapped space: start: 0x%08lx len:%08lx "
- "flags:%08lx, after map:0x%08lx\n",
+ "flags:%08lx, after map:0x%p\n",
pmem_start, pmem_len, pmem_flags,
rtlpriv->io.pci_mem_start));
rtl_deinit_core(hw);
ieee80211_free_hw(hw);
- if (rtlpriv->io.pci_mem_start != 0)
- pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
+ if (rtlpriv->io.pci_mem_start != NULL)
+ pci_iounmap(pdev, rtlpriv->io.pci_mem_start);
fail2:
pci_release_regions(pdev);
pci_disable_msi(rtlpci->pdev);
list_del(&rtlpriv->list);
- if (rtlpriv->io.pci_mem_start != 0) {
- pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
+ if (rtlpriv->io.pci_mem_start != NULL) {
+ pci_iounmap(pdev, rtlpriv->io.pci_mem_start);
pci_release_regions(pdev);
}
* 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, USA
- *
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
void rtl8821ae_read_eeprom_info(struct ieee80211_hw *hw);
void rtl8821ae_interrupt_recognized(struct ieee80211_hw *hw,
- u32 *p_inta, u32 *p_intb);
+ u32 *p_inta, u32 *p_intb);
int rtl8821ae_hw_init(struct ieee80211_hw *hw);
void rtl8821ae_card_disable(struct ieee80211_hw *hw);
void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw);
void rtl8821ae_disable_interrupt(struct ieee80211_hw *hw);
-int rtl8821ae_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
+int rtl8821ae_set_network_type(struct ieee80211_hw *hw,
+ enum nl80211_iftype type);
void rtl8821ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
void rtl8821ae_set_qos(struct ieee80211_hw *hw, int aci);
void rtl8821ae_set_beacon_related_registers(struct ieee80211_hw *hw);
void rtl8821ae_set_beacon_interval(struct ieee80211_hw *hw);
void rtl8821ae_update_interrupt_mask(struct ieee80211_hw *hw,
- u32 add_msr, u32 rm_msr);
+ u32 add_msr, u32 rm_msr);
void rtl8821ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl8821ae_update_hal_rate_tbl(struct ieee80211_hw *hw,
- struct ieee80211_sta *sta,
- u8 rssi_level);
+ struct ieee80211_sta *sta,
+ u8 rssi_level);
void rtl8821ae_update_channel_access_setting(struct ieee80211_hw *hw);
bool rtl8821ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
void rtl8821ae_enable_hw_security_config(struct ieee80211_hw *hw);
void rtl8821ae_set_key(struct ieee80211_hw *hw, u32 key_index,
- u8 *p_macaddr, bool is_group, u8 enc_algo,
- bool is_wepkey, bool clear_all);
+ u8 *p_macaddr, bool is_group, u8 enc_algo,
+ bool is_wepkey, bool clear_all);
void rtl8821ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
- bool autoload_fail,
- u8* hwinfo);
+ bool autoload_fail,
+ u8 *hwinfo);
void rtl8812ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
- bool autoload_fail,
- u8* hwinfo);
-void rtl8821ae_bt_reg_init(struct ieee80211_hw* hw);
-void rtl8821ae_bt_hw_init(struct ieee80211_hw* hw);
+ bool autoload_fail,
+ u8 *hwinfo);
+void rtl8821ae_bt_reg_init(struct ieee80211_hw *hw);
+void rtl8821ae_bt_hw_init(struct ieee80211_hw *hw);
void rtl8821ae_suspend(struct ieee80211_hw *hw);
void rtl8821ae_resume(struct ieee80211_hw *hw);
void rtl8821ae_allow_all_destaddr(struct ieee80211_hw *hw,
- bool allow_all_da,
- bool write_into_reg);
+ bool allow_all_da,
+ bool write_into_reg);
void _rtl8821ae_stop_tx_beacon(struct ieee80211_hw *hw);
void _rtl8821ae_resume_tx_beacon(struct ieee80211_hw *hw);
#endif
struct device *dev;
/*PCI MEM map */
- unsigned long pci_mem_end; /*shared mem end */
- unsigned long pci_mem_start; /*shared mem start */
+ void __iomem *pci_mem_end; /*shared mem end */
+ void __iomem *pci_mem_start; /*shared mem start */
/*PCI IO map */
unsigned long pci_base_addr; /*device I/O address */
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#ifndef T3E3_H
-#define T3E3_H
-
-#include <linux/hdlc.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/io.h>
-#include "ctrl.h"
-
-/**************************************************************
- * 21143
- **************************************************************/
-
-/* CSR */
-#define SBE_2T3E3_21143_REG_BUS_MODE 0
-#define SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND 1
-#define SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND 2
-#define SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS 3
-#define SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS 4
-#define SBE_2T3E3_21143_REG_STATUS 5
-#define SBE_2T3E3_21143_REG_OPERATION_MODE 6
-#define SBE_2T3E3_21143_REG_INTERRUPT_ENABLE 7
-#define SBE_2T3E3_21143_REG_MISSED_FRAMES_AND_OVERFLOW_COUNTER 8
-#define SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT 9
-#define SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS 10
-#define SBE_2T3E3_21143_REG_GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL 11
-#define SBE_2T3E3_21143_REG_SIA_STATUS 12
-#define SBE_2T3E3_21143_REG_SIA_CONNECTIVITY 13
-#define SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE 14
-#define SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT 15
-#define SBE_2T3E3_21143_REG_MAX 16
-
-/* CSR0 - BUS_MODE */
-#define SBE_2T3E3_21143_VAL_WRITE_AND_INVALIDATE_ENABLE 0x01000000
-#define SBE_2T3E3_21143_VAL_READ_LINE_ENABLE 0x00800000
-#define SBE_2T3E3_21143_VAL_READ_MULTIPLE_ENABLE 0x00200000
-#define SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_200us 0x00020000
-#define SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_DISABLED 0x00000000
-#define SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_32 0x0000c000
-#define SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_16 0x00008000
-#define SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_8 0x00004000
-#define SBE_2T3E3_21143_VAL_BUS_ARBITRATION_RR 0x00000002
-#define SBE_2T3E3_21143_VAL_SOFTWARE_RESET 0x00000001
-
-/* CSR5 - STATUS */
-#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_PORT_INTERRUPT 0x04000000
-#define SBE_2T3E3_21143_VAL_ERROR_BITS 0x03800000
-#define SBE_2T3E3_21143_VAL_PARITY_ERROR 0x00000000
-#define SBE_2T3E3_21143_VAL_MASTER_ABORT 0x00800000
-#define SBE_2T3E3_21143_VAL_TARGET_ABORT 0x01000000
-#define SBE_2T3E3_21143_VAL_TRANSMISSION_PROCESS_STATE 0x00700000
-#define SBE_2T3E3_21143_VAL_TX_STOPPED 0x00000000
-#define SBE_2T3E3_21143_VAL_TX_SUSPENDED 0x00600000
-#define SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STATE 0x000e0000
-#define SBE_2T3E3_21143_VAL_RX_STOPPED 0x00000000
-#define SBE_2T3E3_21143_VAL_RX_SUSPENDED 0x000a0000
-#define SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY 0x00010000
-#define SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY 0x00008000
-#define SBE_2T3E3_21143_VAL_EARLY_RECEIVE_INTERRUPT 0x00004000
-#define SBE_2T3E3_21143_VAL_FATAL_BUS_ERROR 0x00002000
-#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_TIMER_EXPIRED 0x00000800
-#define SBE_2T3E3_21143_VAL_EARLY_TRANSMIT_INTERRUPT 0x00000400
-#define SBE_2T3E3_21143_VAL_RECEIVE_WATCHDOG_TIMEOUT 0x00000200
-#define SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED 0x00000100
-#define SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE 0x00000080
-#define SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT 0x00000040
-#define SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW 0x00000020
-#define SBE_2T3E3_21143_VAL_TRANSMIT_JABBER_TIMEOUT 0x00000008
-#define SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE 0x00000004
-#define SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED 0x00000002
-#define SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT 0x00000001
-
-/* CSR6 - OPERATION_MODE */
-#define SBE_2T3E3_21143_VAL_SPECIAL_CAPTURE_EFFECT_ENABLE 0x80000000
-#define SBE_2T3E3_21143_VAL_RECEIVE_ALL 0x40000000
-#define SBE_2T3E3_21143_VAL_MUST_BE_ONE 0x02000000
-#define SBE_2T3E3_21143_VAL_SCRAMBLER_MODE 0x01000000
-#define SBE_2T3E3_21143_VAL_PCS_FUNCTION 0x00800000
-#define SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_10Mbs 0x00400000
-#define SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_100Mbs 0x00000000
-#define SBE_2T3E3_21143_VAL_STORE_AND_FORWARD 0x00200000
-#define SBE_2T3E3_21143_VAL_HEARTBEAT_DISABLE 0x00080000
-#define SBE_2T3E3_21143_VAL_PORT_SELECT 0x00040000
-#define SBE_2T3E3_21143_VAL_CAPTURE_EFFECT_ENABLE 0x00020000
-#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS 0x0000c000
-#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1 0x00000000
-#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2 0x00004000
-#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3 0x00008000
-#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4 0x0000c000
-#define SBE_2T3E3_21143_VAL_TRANSMISSION_START 0x00002000
-#define SBE_2T3E3_21143_VAL_OPERATING_MODE 0x00000c00
-#define SBE_2T3E3_21143_VAL_LOOPBACK_OFF 0x00000000
-#define SBE_2T3E3_21143_VAL_LOOPBACK_EXTERNAL 0x00000800
-#define SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL 0x00000400
-#define SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE 0x00000200
-#define SBE_2T3E3_21143_VAL_PASS_ALL_MULTICAST 0x00000080
-#define SBE_2T3E3_21143_VAL_PROMISCUOUS_MODE 0x00000040
-#define SBE_2T3E3_21143_VAL_PASS_BAD_FRAMES 0x00000008
-#define SBE_2T3E3_21143_VAL_RECEIVE_START 0x00000002
-
-/* CSR7 - INTERRUPT_ENABLE */
-#define SBE_2T3E3_21143_VAL_LINK_CHANGED_ENABLE 0x08000000
-#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_PORT_ENABLE 0x04000000
-#define SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY_ENABLE 0x00010000
-#define SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY_ENABLE 0x00008000
-#define SBE_2T3E3_21143_VAL_EARLY_RECEIVE_INTERRUPT_ENABLE 0x00004000
-#define SBE_2T3E3_21143_VAL_FATAL_BUS_ERROR_ENABLE 0x00002000
-#define SBE_2T3E3_21143_VAL_LINK_FAIL_ENABLE 0x00001000
-#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_TIMER_ENABLE 0x00000800
-#define SBE_2T3E3_21143_VAL_EARLY_TRANSMIT_INTERRUPT_ENABLE 0x00000400
-#define SBE_2T3E3_21143_VAL_RECEIVE_WATCHDOG_TIMEOUT_ENABLE 0x00000200
-#define SBE_2T3E3_21143_VAL_RECEIVE_STOPPED_ENABLE 0x00000100
-#define SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE_ENABLE 0x00000080
-#define SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT_ENABLE 0x00000040
-#define SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW_INTERRUPT_ENABLE 0x00000020
-#define SBE_2T3E3_21143_VAL_TRANSMIT_JABBER_TIMEOUT_ENABLE 0x00000008
-#define SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE_ENABLE 0x00000004
-#define SBE_2T3E3_21143_VAL_TRANSMIT_STOPPED_ENABLE 0x00000002
-#define SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT_ENABLE 0x00000001
-
-/* CSR8 - MISSED_FRAMES_AND_OVERFLOW_COUNTER */
-#define SBE_2T3E3_21143_VAL_OVERFLOW_COUNTER_OVERFLOW 0x10000000
-#define SBE_2T3E3_21143_VAL_OVERFLOW_COUNTER 0x0ffe0000
-#define SBE_2T3E3_21143_VAL_MISSED_FRAME_OVERFLOW 0x00010000
-#define SBE_2T3E3_21143_VAL_MISSED_FRAMES_COUNTER 0x0000ffff
-
-/* CSR9 - BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT */
-#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_DATA_IN 0x00080000
-#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_READ_MODE 0x00040000
-#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_DATA_OUT 0x00020000
-#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_CLOCK 0x00010000
-#define SBE_2T3E3_21143_VAL_READ_OPERATION 0x00004000
-#define SBE_2T3E3_21143_VAL_WRITE_OPERATION 0x00002000
-#define SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT 0x00001000
-#define SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT 0x00000800
-#define SBE_2T3E3_21143_VAL_BOOT_ROM_DATA 0x000000ff
-#define SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_OUT 0x00000008
-#define SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_IN 0x00000004
-#define SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK 0x00000002
-#define SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT 0x00000001
-
-/* CSR11 - GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL */
-#define SBE_2T3E3_21143_VAL_CYCLE_SIZE 0x80000000
-#define SBE_2T3E3_21143_VAL_TRANSMIT_TIMER 0x78000000
-#define SBE_2T3E3_21143_VAL_NUMBER_OF_TRANSMIT_PACKETS 0x07000000
-#define SBE_2T3E3_21143_VAL_RECEIVE_TIMER 0x00f00000
-#define SBE_2T3E3_21143_VAL_NUMBER_OF_RECEIVE_PACKETS 0x000e0000
-#define SBE_2T3E3_21143_VAL_CONTINUOUS_MODE 0x00010000
-#define SBE_2T3E3_21143_VAL_TIMER_VALUE 0x0000ffff
-
-/* CSR12 - SIA_STATUS */
-#define SBE_2T3E3_21143_VAL_10BASE_T_RECEIVE_PORT_ACTIVITY 0x00000200
-#define SBE_2T3E3_21143_VAL_AUI_RECEIVE_PORT_ACTIVITY 0x00000100
-#define SBE_2T3E3_21143_VAL_10Mbs_LINK_STATUS 0x00000004
-#define SBE_2T3E3_21143_VAL_100Mbs_LINK_STATUS 0x00000002
-#define SBE_2T3E3_21143_VAL_MII_RECEIVE_PORT_ACTIVITY 0x00000001
-
-/* CSR13 - SIA_CONNECTIVITY */
-#define SBE_2T3E3_21143_VAL_10BASE_T_OR_AUI 0x00000008
-#define SBE_2T3E3_21143_VAL_SIA_RESET 0x00000001
-
-/* CSR14 - SIA_TRANSMIT_AND_RECEIVE */
-#define SBE_2T3E3_21143_VAL_100BASE_TX_FULL_DUPLEX 0x00020000
-#define SBE_2T3E3_21143_VAL_COLLISION_DETECT_ENABLE 0x00000400
-#define SBE_2T3E3_21143_VAL_COLLISION_SQUELCH_ENABLE 0x00000200
-#define SBE_2T3E3_21143_VAL_RECEIVE_SQUELCH_ENABLE 0x00000100
-#define SBE_2T3E3_21143_VAL_LINK_PULSE_SEND_ENABLE 0x00000004
-#define SBE_2T3E3_21143_VAL_ENCODER_ENABLE 0x00000001
-
-/* CSR15 - SIA_AND_GENERAL_PURPOSE_PORT */
-#define SBE_2T3E3_21143_VAL_RECEIVE_WATCHDOG_DISABLE 0x00000010
-#define SBE_2T3E3_21143_VAL_AUI_BNC_MODE 0x00000008
-#define SBE_2T3E3_21143_VAL_HOST_UNJAB 0x00000002
-#define SBE_2T3E3_21143_VAL_JABBER_DISABLE 0x00000001
-
-/**************************************************************
- * CPLD
- **************************************************************/
-
-/* reg_map indexes */
-#define SBE_2T3E3_CPLD_REG_PCRA 0
-#define SBE_2T3E3_CPLD_REG_PCRB 1
-#define SBE_2T3E3_CPLD_REG_PLCR 2
-#define SBE_2T3E3_CPLD_REG_PLTR 3
-#define SBE_2T3E3_CPLD_REG_PPFR 4
-#define SBE_2T3E3_CPLD_REG_BOARD_ID 5
-#define SBE_2T3E3_CPLD_REG_FPGA_VERSION 6
-#define SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS 7
-#define SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT 8
-#define SBE_2T3E3_CPLD_REG_STATIC_RESET 9
-#define SBE_2T3E3_CPLD_REG_PULSE_RESET 10
-#define SBE_2T3E3_CPLD_REG_FPGA_RECONFIGURATION 11
-#define SBE_2T3E3_CPLD_REG_LEDR 12
-#define SBE_2T3E3_CPLD_REG_PICSR 13
-#define SBE_2T3E3_CPLD_REG_PIER 14
-#define SBE_2T3E3_CPLD_REG_PCRC 15
-#define SBE_2T3E3_CPLD_REG_PBWF 16
-#define SBE_2T3E3_CPLD_REG_PBWL 17
-
-#define SBE_2T3E3_CPLD_REG_MAX 18
-
-/**********/
-
-/* val_map indexes */
-#define SBE_2T3E3_CPLD_VAL_LIU_SELECT 0
-#define SBE_2T3E3_CPLD_VAL_DAC_SELECT 1
-#define SBE_2T3E3_CPLD_VAL_LOOP_TIMING_SOURCE 2
-#define SBE_2T3E3_CPLD_VAL_LIU_FRAMER_RESET 3
-
-/* PCRA */
-#define SBE_2T3E3_CPLD_VAL_CRC32 0x40
-#define SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE 0x20
-#define SBE_2T3E3_CPLD_VAL_REAR_PANEL 0x10
-#define SBE_2T3E3_CPLD_VAL_RAW_MODE 0x08
-#define SBE_2T3E3_CPLD_VAL_ALT 0x04
-#define SBE_2T3E3_CPLD_VAL_LOOP_TIMING 0x02
-#define SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3 0x01
-
-/* PCRB */
-#define SBE_2T3E3_CPLD_VAL_PAD_COUNT 0x30
-#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_1 0x00
-#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_2 0x10
-#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_3 0x20
-#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_4 0x30
-#define SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE 0x02
-#define SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE 0x01
-
-/* PCRC */
-#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE 0x00
-#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0 0x01
-#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1 0x11
-#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2 0x21
-
-/* PLTR */
-#define SBE_2T3E3_CPLD_VAL_LCV_COUNTER 0xff
-
-/* SCSR */
-#define SBE_2T3E3_CPLD_VAL_EEPROM_SELECT 0x10
-
-/* PICSR */
-#define SBE_2T3E3_CPLD_VAL_LOSS_OF_SIGNAL_THRESHOLD_LEVEL_1 0x80
-#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_CHANGE 0x40
-#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ASSERTED 0x20
-#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ASSERTED 0x10
-#define SBE_2T3E3_CPLD_VAL_LCV_LIMIT_EXCEEDED 0x08
-#define SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED 0x04
-#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED 0x02
-#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED 0x01
-
-/* PIER */
-#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOS_CHANGE_ENABLE 0x40
-#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ENABLE 0x20
-#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ENABLE 0x10
-#define SBE_2T3E3_CPLD_VAL_LCV_INTERRUPT_ENABLE 0x08
-#define SBE_2T3E3_CPLD_VAL_DMO_ENABLE 0x04
-#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_ENABLE 0x02
-#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_ENABLE 0x01
-
-/**************************************************************
- * Framer
- **************************************************************/
-
-/* reg_map indexes */
-/* common */
-#define SBE_2T3E3_FRAMER_REG_OPERATING_MODE 0
-#define SBE_2T3E3_FRAMER_REG_IO_CONTROL 1
-#define SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE 2
-#define SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS 3
-#define SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_MSB 28
-#define SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_LSB 29
-#define SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB 30
-#define SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_LSB 31
-#define SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_MSB 32
-#define SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_LSB 33
-#define SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_MSB 34
-#define SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_LSB 35
-#define SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_MSB 36
-#define SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_LSB 37
-#define SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER 38
-#define SBE_2T3E3_FRAMER_REG_ONE_SECOND_ERROR_STATUS 39
-#define SBE_2T3E3_FRAMER_REG_LCV_ONE_SECOND_ACCUMULATOR_MSB 40
-#define SBE_2T3E3_FRAMER_REG_LCV_ONE_SECOND_ACCUMULATOR_LSB 41
-#define SBE_2T3E3_FRAMER_REG_FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_MSB 42
-#define SBE_2T3E3_FRAMER_REG_FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_LSB 43
-#define SBE_2T3E3_FRAMER_REG_FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_MSB 44
-#define SBE_2T3E3_FRAMER_REG_FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_LSB 45
-#define SBE_2T3E3_FRAMER_REG_LINE_INTERFACE_DRIVE 46
-#define SBE_2T3E3_FRAMER_REG_LINE_INTERFACE_SCAN 47
-
-/* T3 */
-#define SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS 4
-#define SBE_2T3E3_FRAMER_REG_T3_RX_STATUS 5
-#define SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE 6
-#define SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS 7
-#define SBE_2T3E3_FRAMER_REG_T3_RX_SYNC_DETECT_ENABLE 8
-#define SBE_2T3E3_FRAMER_REG_T3_RX_FEAC 10
-#define SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS 11
-#define SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL 12
-#define SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_STATUS 13
-#define SBE_2T3E3_FRAMER_REG_T3_TX_CONFIGURATION 16
-#define SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS 17
-#define SBE_2T3E3_FRAMER_REG_T3_TX_FEAC 18
-#define SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_CONFIGURATION 19
-#define SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS 20
-#define SBE_2T3E3_FRAMER_REG_T3_TX_MBIT_MASK 21
-#define SBE_2T3E3_FRAMER_REG_T3_TX_FBIT_MASK 22
-#define SBE_2T3E3_FRAMER_REG_T3_TX_FBIT_MASK_2 23
-#define SBE_2T3E3_FRAMER_REG_T3_TX_FBIT_MASK_3 24
-
-/* E3 */
-#define SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_1 4
-#define SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2 5
-#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1 6
-#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2 7
-#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1 8
-#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2 9
-#define SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL 12
-#define SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_STATUS 13
-#define SBE_2T3E3_FRAMER_REG_E3_RX_NR_BYTE 14
-#define SBE_2T3E3_FRAMER_REG_E3_RX_SERVICE_BITS 14
-#define SBE_2T3E3_FRAMER_REG_E3_RX_GC_BYTE 15
-#define SBE_2T3E3_FRAMER_REG_E3_TX_CONFIGURATION 16
-#define SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_CONFIGURATION 19
-#define SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS 19
-#define SBE_2T3E3_FRAMER_REG_E3_TX_GC_BYTE 21
-#define SBE_2T3E3_FRAMER_REG_E3_TX_SERVICE_BITS 21
-#define SBE_2T3E3_FRAMER_REG_E3_TX_MA_BYTE 22
-#define SBE_2T3E3_FRAMER_REG_E3_TX_NR_BYTE 23
-#define SBE_2T3E3_FRAMER_REG_E3_TX_FA1_ERROR_MASK 25
-#define SBE_2T3E3_FRAMER_REG_E3_TX_FAS_ERROR_MASK_UPPER 25
-#define SBE_2T3E3_FRAMER_REG_E3_TX_FA2_ERROR_MASK 26
-#define SBE_2T3E3_FRAMER_REG_E3_TX_FAS_ERROR_MASK_LOWER 26
-#define SBE_2T3E3_FRAMER_REG_E3_TX_BIP8_MASK 27
-#define SBE_2T3E3_FRAMER_REG_E3_TX_BIP4_MASK 27
-
-#define SBE_2T3E3_FRAMER_REG_MAX 48
-
-/**********/
-
-/* OPERATING_MODE */
-#define SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE 0x80
-#define SBE_2T3E3_FRAMER_VAL_T3_E3_SELECT 0x40
-#define SBE_2T3E3_FRAMER_VAL_INTERNAL_LOS_ENABLE 0x20
-#define SBE_2T3E3_FRAMER_VAL_RESET 0x10
-#define SBE_2T3E3_FRAMER_VAL_INTERRUPT_ENABLE_RESET 0x08
-#define SBE_2T3E3_FRAMER_VAL_FRAME_FORMAT_SELECT 0x04
-#define SBE_2T3E3_FRAMER_VAL_TIMING_ASYNCH_TXINCLK 0x03
-#define SBE_2T3E3_FRAMER_VAL_E3_G751 0x00
-#define SBE_2T3E3_FRAMER_VAL_E3_G832 0x04
-#define SBE_2T3E3_FRAMER_VAL_T3_CBIT 0x40
-#define SBE_2T3E3_FRAMER_VAL_T3_M13 0x44
-#define SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON 0x80
-#define SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF 0x00
-
-/* IO_CONTROL */
-#define SBE_2T3E3_FRAMER_VAL_DISABLE_TX_LOSS_OF_CLOCK 0x80
-#define SBE_2T3E3_FRAMER_VAL_LOSS_OF_CLOCK_STATUS 0x40
-#define SBE_2T3E3_FRAMER_VAL_DISABLE_RX_LOSS_OF_CLOCK 0x20
-#define SBE_2T3E3_FRAMER_VAL_AMI_LINE_CODE 0x10
-#define SBE_2T3E3_FRAMER_VAL_UNIPOLAR 0x08
-#define SBE_2T3E3_FRAMER_VAL_TX_LINE_CLOCK_INVERT 0x04
-#define SBE_2T3E3_FRAMER_VAL_RX_LINE_CLOCK_INVERT 0x02
-#define SBE_2T3E3_FRAMER_VAL_REFRAME 0x01
-
-/* BLOCK_INTERRUPT_ENABLE */
-#define SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE 0x80
-#define SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE 0x02
-#define SBE_2T3E3_FRAMER_VAL_ONE_SECOND_INTERRUPT_ENABLE 0x01
-
-/* BLOCK_INTERRUPT_STATUS */
-#define SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS 0x80
-#define SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS 0x02
-#define SBE_2T3E3_FRAMER_VAL_ONE_SECOND_INTERRUPT_STATUS 0x01
-
-/**********/
-
-/* T3_RX_CONFIGURATION_STATUS */
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIS 0x80
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_LOS 0x40
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE 0x20
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_OOF 0x10
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_FRAMING_ON_PARITY 0x04
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_F_SYNC_ALGO 0x02
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_M_SYNC_ALGO 0x01
-
-/* T3_RX_STATUS */
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_FERF 0x10
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIC 0x04
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEBE 0x07
-
-/* T3_RX_INTERRUPT_ENABLE */
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_ENABLE 0x80
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE 0x40
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_ENABLE 0x20
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_ENABLE 0x10
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_ENABLE 0x08
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_ENABLE 0x04
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE 0x02
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_ENABLE 0x01
-
-/* T3_RX_INTERRUPT_STATUS */
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_STATUS 0x80
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_STATUS 0x40
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_STATUS 0x20
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_STATUS 0x10
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_STATUS 0x08
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_STATUS 0x04
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_STATUS 0x02
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_STATUS 0x01
-
-/* T3_RX_FEAC_INTERRUPT_ENABLE_STATUS */
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID 0x10
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_ENABLE 0x08
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_STATUS 0x04
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_ENABLE 0x02
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_STATUS 0x01
-
-/* T3_RX_LAPD_CONTROL */
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_ENABLE 0x04
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_INTERRUPT_ENABLE 0x02
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_INTERRUPT_STATUS 0x01
-
-/* T3_RX_LAPD_STATUS */
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_ABORT 0x40
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_TYPE 0x30
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_CR_TYPE 0x08
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_FCS_ERROR 0x04
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_END_OF_MESSAGE 0x02
-#define SBE_2T3E3_FRAMER_VAL_T3_RX_FLAG_PRESENT 0x01
-
-/* T3_TX_CONFIGURATION */
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_YELLOW_ALARM 0x80
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_X_BIT 0x40
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_IDLE 0x20
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_AIS 0x10
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_LOS 0x08
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_FERF_ON_LOS 0x04
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_FERF_ON_OOF 0x02
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_FERF_ON_AIS 0x01
-
-/* T3_TX_FEAC_CONFIGURATION_STATUS */
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_INTERRUPT_ENABLE 0x10
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_INTERRUPT_STATUS 0x08
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_ENABLE 0x04
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_GO 0x02
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_BUSY 0x01
-
-/* T3_TX_LAPD_STATUS */
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_DL_START 0x08
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_DL_BUSY 0x04
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_LAPD_INTERRUPT_ENABLE 0x02
-#define SBE_2T3E3_FRAMER_VAL_T3_TX_LAPD_INTERRUPT_STATUS 0x01
-
-/**********/
-
-/* E3_RX_CONFIGURATION_STATUS_1 */
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_TYPE 0xe0
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_ALGO 0x10
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_T_MARK_ALGO 0x08
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_EXPECTED 0x07
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP4 0x01
-
-/* E3_RX_CONFIGURATION_STATUS_2 */
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_ALGO 0x80
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF 0x40
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_OOF 0x20
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOS 0x10
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_AIS 0x08
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_UNSTABLE 0x04
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_T_MARK 0x02
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF 0x01
-
-/* E3_RX_INTERRUPT_ENABLE_1 */
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_ENABLE 0x10
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE 0x08
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_ENABLE 0x04
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE 0x02
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_ENABLE 0x01
-
-/* E3_RX_INTERRUPT_ENABLE_2 */
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_TTB_CHANGE_INTERRUPT_ENABLE 0x40
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_ENABLE 0x10
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_ENABLE 0x08
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP8_ERROR_INTERRUPT_ENABLE 0x04
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP4_ERROR_INTERRUPT_ENABLE 0x04
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_ENABLE 0x02
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_MISMATCH_INTERRUPT_ENABLE 0x01
-
-/* E3_RX_INTERRUPT_STATUS_1 */
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_STATUS 0x10
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_STATUS 0x08
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_STATUS 0x04
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_STATUS 0x02
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_STATUS 0x01
-
-/* E3_RX_INTERRUPT_STATUS_2 */
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_TTB_CHANGE_INTERRUPT_STATUS 0x40
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_STATUS 0x10
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_STATUS 0x08
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP8_ERROR_INTERRUPT_STATUS 0x04
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP4_ERROR_INTERRUPT_STATUS 0x04
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_STATUS 0x02
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_MISMATCH_INTERRUPT_STATUS 0x01
-
-/* E3_RX_LAPD_CONTROL */
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_DL_FROM_NR 0x08
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_ENABLE 0x04
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_INTERRUPT_ENABLE 0x02
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_INTERRUPT_STATUS 0x01
-
-/* E3_RX_LAPD_STATUS */
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_ABORT 0x40
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_TYPE 0x30
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_CR_TYPE 0x08
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_FCS_ERROR 0x04
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_END_OF_MESSAGE 0x02
-#define SBE_2T3E3_FRAMER_VAL_E3_RX_FLAG_PRESENT 0x01
-
-/* E3_TX_CONFIGURATION */
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_BIP4_ENABLE 0x80
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_A_SOURCE_SELECT 0x60
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_DL_IN_NR 0x10
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_N_SOURCE_SELECT 0x18
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_AIS_ENABLE 0x04
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_LOS_ENABLE 0x02
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_MA_RX 0x01
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_FAS_SOURCE_SELECT 0x01
-
-/* E3_TX_LAPD_CONFIGURATION */
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_AUTO_RETRANSMIT 0x08
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_MESSAGE_LENGTH 0x02
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_ENABLE 0x01
-
-/* E3_TX_LAPD_STATUS_INTERRUPT */
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_DL_START 0x08
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_DL_BUSY 0x04
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_INTERRUPT_ENABLE 0x02
-#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_INTERRUPT_STATUS 0x01
-
-
-
-
-
-
-/**************************************************************
- * LIU
- **************************************************************/
-
-/* reg_map indexes */
-#define SBE_2T3E3_LIU_REG_REG0 0
-#define SBE_2T3E3_LIU_REG_REG1 1
-#define SBE_2T3E3_LIU_REG_REG2 2
-#define SBE_2T3E3_LIU_REG_REG3 3
-#define SBE_2T3E3_LIU_REG_REG4 4
-
-#define SBE_2T3E3_LIU_REG_MAX 5
-
-/**********/
-
-/* REG0 */
-#define SBE_2T3E3_LIU_VAL_RECEIVE_LOSS_OF_LOCK_STATUS 0x10
-#define SBE_2T3E3_LIU_VAL_RECEIVE_LOSS_OF_SIGNAL_STATUS 0x08
-#define SBE_2T3E3_LIU_VAL_ANALOG_LOSS_OF_SIGNAL_STATUS 0x04
-#define SBE_2T3E3_LIU_VAL_DIGITAL_LOSS_OF_SIGNAL_STATUS 0x02
-#define SBE_2T3E3_LIU_VAL_DMO_STATUS 0x01
-
-/* REG1 */
-#define SBE_2T3E3_LIU_VAL_TRANSMITTER_OFF 0x10
-#define SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES 0x08
-#define SBE_2T3E3_LIU_VAL_TRANSMIT_CLOCK_INVERT 0x04
-#define SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT 0x02
-#define SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA 0x01
-
-/* REG2 */
-#define SBE_2T3E3_LIU_VAL_DECODER_DISABLE 0x10
-#define SBE_2T3E3_LIU_VAL_ENCODER_DISABLE 0x08
-#define SBE_2T3E3_LIU_VAL_ANALOG_LOSS_OF_SIGNAL_DISABLE 0x04
-#define SBE_2T3E3_LIU_VAL_DIGITAL_LOSS_OF_SIGNAL_DISABLE 0x02
-#define SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE 0x01
-
-/* REG3 */
-#define SBE_2T3E3_LIU_VAL_RECEIVE_BINARY_DATA 0x10
-#define SBE_2T3E3_LIU_VAL_RECOVERED_DATA_MUTING 0x08
-#define SBE_2T3E3_LIU_VAL_RECEIVE_CLOCK_OUTPUT_2 0x04
-#define SBE_2T3E3_LIU_VAL_INVERT_RECEIVE_CLOCK_2 0x02
-#define SBE_2T3E3_LIU_VAL_INVERT_RECEIVE_CLOCK_1 0x01
-
-/* REG4 */
-#define SBE_2T3E3_LIU_VAL_T3_MODE_SELECT 0x00
-#define SBE_2T3E3_LIU_VAL_E3_MODE_SELECT 0x04
-#define SBE_2T3E3_LIU_VAL_LOCAL_LOOPBACK 0x02
-#define SBE_2T3E3_LIU_VAL_REMOTE_LOOPBACK 0x01
-#define SBE_2T3E3_LIU_VAL_LOOPBACK_OFF 0x00
-#define SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE 0x01
-#define SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG 0x02
-#define SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL 0x03
-
-/**********************************************************************
- *
- * descriptor list and data buffer
- *
- **********************************************************************/
-struct t3e3_rx_desc {
- u32 rdes0;
- u32 rdes1;
- u32 rdes2;
- u32 rdes3;
-};
-
-#define SBE_2T3E3_RX_DESC_RING_SIZE 64
-
-/* RDES0 */
-#define SBE_2T3E3_RX_DESC_21143_OWN 0X80000000
-#define SBE_2T3E3_RX_DESC_FRAME_LENGTH 0x3fff0000
-#define SBE_2T3E3_RX_DESC_FRAME_LENGTH_SHIFT 16
-#define SBE_2T3E3_RX_DESC_ERROR_SUMMARY 0x00008000
-#define SBE_2T3E3_RX_DESC_DESC_ERROR 0x00004000
-#define SBE_2T3E3_RX_DESC_DATA_TYPE 0x00003000
-#define SBE_2T3E3_RX_DESC_RUNT_FRAME 0x00000800
-#define SBE_2T3E3_RX_DESC_FIRST_DESC 0x00000200
-#define SBE_2T3E3_RX_DESC_LAST_DESC 0x00000100
-#define SBE_2T3E3_RX_DESC_FRAME_TOO_LONG 0x00000080
-#define SBE_2T3E3_RX_DESC_COLLISION_SEEN 0x00000040
-#define SBE_2T3E3_RX_DESC_FRAME_TYPE 0x00000020
-#define SBE_2T3E3_RX_DESC_RECEIVE_WATCHDOG 0x00000010
-#define SBE_2T3E3_RX_DESC_MII_ERROR 0x00000008
-#define SBE_2T3E3_RX_DESC_DRIBBLING_BIT 0x00000004
-#define SBE_2T3E3_RX_DESC_CRC_ERROR 0x00000002
-
-/* RDES1 */
-#define SBE_2T3E3_RX_DESC_END_OF_RING 0x02000000
-#define SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED 0x01000000
-#define SBE_2T3E3_RX_DESC_BUFFER_2_SIZE 0x003ff800
-#define SBE_2T3E3_RX_DESC_BUFFER_1_SIZE 0x000007ff
-
-/*********************/
-
-struct t3e3_tx_desc {
- u32 tdes0;
- u32 tdes1;
- u32 tdes2;
- u32 tdes3;
-};
-
-#define SBE_2T3E3_TX_DESC_RING_SIZE 256
-
-/* TDES0 */
-#define SBE_2T3E3_TX_DESC_21143_OWN 0x80000000
-#define SBE_2T3E3_TX_DESC_ERROR_SUMMARY 0x00008000
-#define SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT 0x00004000
-#define SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER 0x00000800
-#define SBE_2T3E3_TX_DESC_NO_CARRIER 0x00000400
-#define SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT 0x00000004
-#define SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR 0x00000002
-#define SBE_2T3E3_TX_DESC_DEFFERED 0x00000001
-
-/* TDES1 */
-#define SBE_2T3E3_TX_DESC_INTERRUPT_ON_COMPLETION 0x80000000
-#define SBE_2T3E3_TX_DESC_LAST_SEGMENT 0x40000000
-#define SBE_2T3E3_TX_DESC_FIRST_SEGMENT 0x20000000
-#define SBE_2T3E3_TX_DESC_CRC_DISABLE 0x04000000
-#define SBE_2T3E3_TX_DESC_END_OF_RING 0x02000000
-#define SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED 0x01000000
-#define SBE_2T3E3_TX_DESC_DISABLE_PADDING 0x00800000
-#define SBE_2T3E3_TX_DESC_BUFFER_2_SIZE 0x003ff800
-#define SBE_2T3E3_TX_DESC_BUFFER_1_SIZE 0x000007ff
-
-
-#define SBE_2T3E3_MTU 1600
-#define SBE_2T3E3_CRC16_LENGTH 2
-#define SBE_2T3E3_CRC32_LENGTH 4
-
-#define MCLBYTES (SBE_2T3E3_MTU + 128)
-
-struct channel {
- struct pci_dev *pdev;
- struct net_device *dev;
- struct card *card;
- unsigned long addr; /* DECchip */
-
- int leds;
-
- /* pci specific */
- struct {
- u32 slot; /* should be 0 or 1 */
- u32 command;
- u8 cache_size;
- } h;
-
- /* statistics */
- struct t3e3_stats s;
-
- /* running */
- struct {
- u32 flags;
- } r;
-
- /* parameters */
- struct t3e3_param p;
-
- u32 liu_regs[SBE_2T3E3_LIU_REG_MAX]; /* LIU registers */
- u32 framer_regs[SBE_2T3E3_FRAMER_REG_MAX]; /* Framer registers */
-
- /* Ethernet Controller */
- struct {
- u_int16_t card_serial_number[3];
-
- u32 reg[SBE_2T3E3_21143_REG_MAX]; /* registers i.e. CSR */
-
- u32 interrupt_enable_mask;
-
- /* receive chain/ring */
- struct t3e3_rx_desc *rx_ring;
- struct sk_buff *rx_data[SBE_2T3E3_RX_DESC_RING_SIZE];
- u32 rx_ring_current_read;
-
- /* transmit chain/ring */
- struct t3e3_tx_desc *tx_ring;
- struct sk_buff *tx_data[SBE_2T3E3_TX_DESC_RING_SIZE];
- u32 tx_ring_current_read;
- u32 tx_ring_current_write;
- int tx_full;
- int tx_free_cnt;
- spinlock_t tx_lock;
- } ether;
-
- int32_t interrupt_active;
- int32_t rcv_count;
-};
-
-struct card {
- spinlock_t bootrom_lock;
- unsigned long bootrom_addr;
- struct timer_list timer; /* for updating LEDs */
- struct channel channels[0];
-};
-
-#define SBE_2T3E3_FLAG_NETWORK_UP 0x00000001
-#define SBE_2T3E3_FLAG_NO_ERROR_MESSAGES 0x00000002
-
-extern const u32 cpld_reg_map[][2];
-extern const u32 cpld_val_map[][2];
-extern const u32 t3e3_framer_reg_map[];
-extern const u32 t3e3_liu_reg_map[];
-
-void t3e3_init(struct channel *);
-void t3e3_if_up(struct channel *);
-void t3e3_if_down(struct channel *);
-int t3e3_if_start_xmit(struct sk_buff *skb, struct net_device *dev);
-void t3e3_if_config(struct channel *, u32, char *, struct t3e3_resp *, int *);
-void t3e3_set_frame_type(struct channel *, u32);
-u32 t3e3_eeprom_read_word(struct channel *, u32);
-void t3e3_read_card_serial_number(struct channel *);
-
-/* interrupt handlers */
-irqreturn_t t3e3_intr(int irq, void *dev_instance);
-void dc_intr(struct channel *);
-void dc_intr_rx(struct channel *);
-void dc_intr_tx(struct channel *);
-void dc_intr_tx_underflow(struct channel *);
-void exar7250_intr(struct channel *);
-void exar7250_E3_intr(struct channel *, u32);
-void exar7250_T3_intr(struct channel *, u32);
-
-/* Ethernet controller */
-u32 bootrom_read(struct channel *, u32);
-void bootrom_write(struct channel *, u32, u32);
-void dc_init(struct channel *);
-void dc_start(struct channel *);
-void dc_stop(struct channel *);
-void dc_start_intr(struct channel *);
-void dc_stop_intr(struct channel *);
-void dc_reset(struct channel *);
-void dc_restart(struct channel *);
-void dc_receiver_onoff(struct channel *, u32);
-void dc_transmitter_onoff(struct channel *, u32);
-void dc_set_loopback(struct channel *, u32);
-void dc_clear_descriptor_list(struct channel *);
-void dc_drop_descriptor_list(struct channel *);
-void dc_set_output_port(struct channel *);
-void t3e3_sc_init(struct channel *);
-
-/* CPLD */
-void cpld_init(struct channel *sc);
-u32 cpld_read(struct channel *sc, u32 reg);
-void cpld_set_crc(struct channel *, u32);
-void cpld_start_intr(struct channel *);
-void cpld_stop_intr(struct channel *);
-void cpld_set_clock(struct channel *sc, u32 mode);
-void cpld_set_scrambler(struct channel *, u32);
-void cpld_select_panel(struct channel *, u32);
-void cpld_set_frame_mode(struct channel *, u32);
-void cpld_set_frame_type(struct channel *, u32);
-void cpld_set_pad_count(struct channel *, u32);
-void cpld_set_fractional_mode(struct channel *, u32, u32, u32);
-void cpld_LOS_update(struct channel *);
-
-/* Framer */
-extern u32 exar7250_read(struct channel *, u32);
-extern void exar7250_write(struct channel *, u32, u32);
-void exar7250_init(struct channel *);
-void exar7250_start_intr(struct channel *, u32);
-void exar7250_stop_intr(struct channel *, u32);
-void exar7250_set_frame_type(struct channel *, u32);
-void exar7250_set_loopback(struct channel *, u32);
-void exar7250_unipolar_onoff(struct channel *, u32);
-
-/* LIU */
-u32 exar7300_read(struct channel *, u32);
-void exar7300_write(struct channel *, u32, u32);
-void exar7300_init(struct channel *);
-void exar7300_line_build_out_onoff(struct channel *, u32);
-void exar7300_set_frame_type(struct channel *, u32);
-void exar7300_set_loopback(struct channel *, u32);
-void exar7300_transmit_all_ones_onoff(struct channel *, u32);
-void exar7300_receive_equalization_onoff(struct channel *, u32);
-void exar7300_unipolar_onoff(struct channel *, u32);
-
-void update_led(struct channel *, int);
-int setup_device(struct net_device *dev, struct channel *sc);
-
-static inline int has_two_ports(struct pci_dev *pdev)
-{
- return pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P0;
-}
-
-#define dev_to_priv(dev) (*(struct channel **) ((hdlc_device *)(dev) + 1))
-
-static inline u32 dc_read(unsigned long addr, u32 reg)
-{
- return inl(addr + (reg << 3));
-}
-
-static inline void dc_write(unsigned long addr, u32 reg, u32 val)
-{
- outl(val, addr + (reg << 3));
-}
-
-static inline void dc_set_bits(unsigned long addr, u32 reg, u32 bits)
-{
- dc_write(addr, reg, dc_read(addr, reg) | bits);
-}
-
-static inline void dc_clear_bits(unsigned long addr, u32 reg, u32 bits)
-{
- dc_write(addr, reg, dc_read(addr, reg) & ~bits);
-}
-
-#define CPLD_MAP_REG(reg, sc) (cpld_reg_map[(reg)][(sc)->h.slot])
-
-static inline void cpld_write(struct channel *channel, unsigned reg, u32 val)
-{
- unsigned long flags;
- spin_lock_irqsave(&channel->card->bootrom_lock, flags);
- bootrom_write(channel, CPLD_MAP_REG(reg, channel), val);
- spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
-}
-
-#define exar7250_set_bit(sc, reg, bit) \
- exar7250_write((sc), (reg), \
- exar7250_read(sc, reg) | (bit))
-
-#define exar7250_clear_bit(sc, reg, bit) \
- exar7250_write((sc), (reg), \
- exar7250_read(sc, reg) & ~(bit))
-
-#define exar7300_set_bit(sc, reg, bit) \
- exar7300_write((sc), (reg), \
- exar7300_read(sc, reg) | (bit))
-
-#define exar7300_clear_bit(sc, reg, bit) \
- exar7300_write((sc), (reg), \
- exar7300_read(sc, reg) & ~(bit))
-
-
-#endif /* T3E3_H */
+++ /dev/null
-config SBE_2T3E3
- tristate "SBE wanPMC-2T3E3 support"
- depends on HDLC && PCI
- help
- Driver for wanPMC-2T3E3 cards by SBE Inc.
-
- If you have such a card, say Y here and see
- <http://www.kernel.org/pub/linux/utils/net/hdlc/>.
-
- To compile this as a module, choose M here: the
- module will be called sbe-2t3e3.
-
- If unsure, say N.
+++ /dev/null
-obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3.o
-
-sbe-2t3e3-y := module.o netdev.o maps.o \
- main.o cpld.o intr.o ctrl.o io.o dc.o exar7250.o exar7300.o
+++ /dev/null
-TODO:
- - additional cleaning and tests
- - wait for the new configuration interface in generic HDLC layer and
- when available, convert the driver to it
-
-Please send patches to Krzysztof Halasa <khc@pm.waw.pl>.
\ No newline at end of file
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#include <linux/delay.h>
-#include "2t3e3.h"
-#include "ctrl.h"
-
-#define bootrom_set_bit(sc, reg, bit) \
- bootrom_write((sc), (reg), \
- bootrom_read((sc), (reg)) | (bit))
-
-#define bootrom_clear_bit(sc, reg, bit) \
- bootrom_write((sc), (reg), \
- bootrom_read((sc), (reg)) & ~(bit))
-
-static inline void cpld_set_bit(struct channel *channel, unsigned reg, u32 bit)
-{
- unsigned long flags;
- spin_lock_irqsave(&channel->card->bootrom_lock, flags);
- bootrom_set_bit(channel, CPLD_MAP_REG(reg, channel), bit);
- spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
-}
-
-static inline void cpld_clear_bit(struct channel *channel, unsigned reg, u32 bit)
-{
- unsigned long flags;
- spin_lock_irqsave(&channel->card->bootrom_lock, flags);
- bootrom_clear_bit(channel, CPLD_MAP_REG(reg, channel), bit);
- spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
-}
-
-void cpld_init(struct channel *sc)
-{
- u32 val;
-
- /* PCRA */
- val = SBE_2T3E3_CPLD_VAL_CRC32 |
- cpld_val_map[SBE_2T3E3_CPLD_VAL_LOOP_TIMING_SOURCE][sc->h.slot];
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRA, val);
-
- /* PCRB */
- val = 0;
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
-
- /* PCRC */
- val = 0;
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC, val);
-
- /* PBWF */
- val = 0;
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, val);
-
- /* PBWL */
- val = 0;
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, val);
-
- /* PLTR */
- val = SBE_2T3E3_CPLD_VAL_LCV_COUNTER;
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PLTR, val);
- udelay(1000);
-
- /* PLCR */
- val = 0;
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PLCR, val);
- udelay(1000);
-
- /* PPFR */
- val = 0x55;
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PPFR, val);
- /* TODO: this doesn't work!!! */
-
- /* SERIAL_CHIP_SELECT */
- val = 0;
- cpld_write(sc, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, val);
-
- /* PICSR */
- val = SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED |
- SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED |
- SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED;
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR, val);
-
- cpld_start_intr(sc);
-
- udelay(1000);
-}
-
-void cpld_start_intr(struct channel *sc)
-{
- u32 val;
-
- /* PIER */
- val = SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ENABLE |
- SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ENABLE;
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
-}
-
-void cpld_stop_intr(struct channel *sc)
-{
- u32 val;
-
- /* PIER */
- val = 0;
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
-}
-
-void cpld_set_frame_mode(struct channel *sc, u32 mode)
-{
- if (sc->p.frame_mode == mode)
- return;
-
- switch (mode) {
- case SBE_2T3E3_FRAME_MODE_HDLC:
- cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
- SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE |
- SBE_2T3E3_CPLD_VAL_RAW_MODE);
- exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF);
- exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF);
- break;
- case SBE_2T3E3_FRAME_MODE_TRANSPARENT:
- cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
- SBE_2T3E3_CPLD_VAL_RAW_MODE);
- cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
- SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE);
- exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF);
- exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF);
- break;
- case SBE_2T3E3_FRAME_MODE_RAW:
- cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
- SBE_2T3E3_CPLD_VAL_RAW_MODE);
- exar7250_unipolar_onoff(sc, SBE_2T3E3_ON);
- exar7300_unipolar_onoff(sc, SBE_2T3E3_ON);
- break;
- default:
- return;
- }
-
- sc->p.frame_mode = mode;
-}
-
-/* set rate of the local clock */
-void cpld_set_frame_type(struct channel *sc, u32 type)
-{
- switch (type) {
- case SBE_2T3E3_FRAME_TYPE_E3_G751:
- case SBE_2T3E3_FRAME_TYPE_E3_G832:
- cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
- SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3);
- break;
- case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
- case SBE_2T3E3_FRAME_TYPE_T3_M13:
- cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
- SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3);
- break;
- default:
- return;
- }
-}
-
-void cpld_set_scrambler(struct channel *sc, u32 mode)
-{
- if (sc->p.scrambler == mode)
- return;
-
- switch (mode) {
- case SBE_2T3E3_SCRAMBLER_OFF:
- cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
- SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
- break;
- case SBE_2T3E3_SCRAMBLER_LARSCOM:
- cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
- SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE);
- cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
- SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
- break;
- case SBE_2T3E3_SCRAMBLER_ADC_KENTROX_DIGITAL:
- cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
- SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE);
- cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
- SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
- break;
- default:
- return;
- }
-
- sc->p.scrambler = mode;
-}
-
-
-void cpld_set_crc(struct channel *sc, u32 crc)
-{
- if (sc->p.crc == crc)
- return;
-
- switch (crc) {
- case SBE_2T3E3_CRC_16:
- cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
- SBE_2T3E3_CPLD_VAL_CRC32);
- break;
- case SBE_2T3E3_CRC_32:
- cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
- SBE_2T3E3_CPLD_VAL_CRC32);
- break;
- default:
- return;
- }
-
- sc->p.crc = crc;
-}
-
-
-void cpld_select_panel(struct channel *sc, u32 panel)
-{
- if (sc->p.panel == panel)
- return;
- switch (panel) {
- case SBE_2T3E3_PANEL_FRONT:
- cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
- SBE_2T3E3_CPLD_VAL_REAR_PANEL);
- break;
- case SBE_2T3E3_PANEL_REAR:
- cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
- SBE_2T3E3_CPLD_VAL_REAR_PANEL);
- break;
- default:
- return;
- }
-
- udelay(100);
-
- sc->p.panel = panel;
-}
-
-
-void cpld_set_clock(struct channel *sc, u32 mode)
-{
- if (sc->p.clock_source == mode)
- return;
-
- switch (mode) {
- case SBE_2T3E3_TIMING_LOCAL:
- cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
- SBE_2T3E3_CPLD_VAL_ALT);
- break;
- case SBE_2T3E3_TIMING_LOOP:
- cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
- SBE_2T3E3_CPLD_VAL_ALT);
- break;
- default:
- return;
- }
-
- sc->p.clock_source = mode;
-}
-
-void cpld_set_pad_count(struct channel *sc, u32 count)
-{
- u32 val;
-
- if (sc->p.pad_count == count)
- return;
-
- switch (count) {
- case SBE_2T3E3_PAD_COUNT_1:
- val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_1;
- break;
- case SBE_2T3E3_PAD_COUNT_2:
- val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_2;
- break;
- case SBE_2T3E3_PAD_COUNT_3:
- val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_3;
- break;
- case SBE_2T3E3_PAD_COUNT_4:
- val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_4;
- break;
- default:
- return;
- }
-
- cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
- SBE_2T3E3_CPLD_VAL_PAD_COUNT);
- cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
- sc->p.pad_count = count;
-}
-
-void cpld_LOS_update(struct channel *sc)
-{
- u_int8_t los;
-
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR,
- SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED |
- SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED |
- SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED);
- los = cpld_read(sc, SBE_2T3E3_CPLD_REG_PICSR) &
- SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED;
-
- if (los != sc->s.LOS)
- dev_info(&sc->pdev->dev, "SBE 2T3E3: LOS status: %s\n",
- los ? "Loss of signal" : "Signal OK");
- sc->s.LOS = los;
-}
-
-void cpld_set_fractional_mode(struct channel *sc, u32 mode,
- u32 start, u32 stop)
-{
- if (mode == SBE_2T3E3_FRACTIONAL_MODE_NONE) {
- start = 0;
- stop = 0;
- }
-
- if (sc->p.fractional_mode == mode && sc->p.bandwidth_start == start &&
- sc->p.bandwidth_stop == stop)
- return;
-
- switch (mode) {
- case SBE_2T3E3_FRACTIONAL_MODE_NONE:
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
- SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE);
- break;
- case SBE_2T3E3_FRACTIONAL_MODE_0:
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
- SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0);
- break;
- case SBE_2T3E3_FRACTIONAL_MODE_1:
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
- SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1);
- break;
- case SBE_2T3E3_FRACTIONAL_MODE_2:
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
- SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2);
- break;
- default:
- netdev_err(sc->dev, "wrong mode in set_fractional_mode\n");
- return;
- }
-
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, start);
- cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, stop);
-
- sc->p.fractional_mode = mode;
- sc->p.bandwidth_start = start;
- sc->p.bandwidth_stop = stop;
-}
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#include <linux/types.h>
-#include "2t3e3.h"
-#include "ctrl.h"
-
-void t3e3_set_frame_type(struct channel *sc, u32 mode)
-{
- if (sc->p.frame_type == mode)
- return;
-
- if (sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP) {
- dev_err(&sc->pdev->dev, "SBE 2T3E3: changing frame type during active connection\n");
- return;
- }
-
- exar7300_set_frame_type(sc, mode);
- exar7250_set_frame_type(sc, mode);
- cpld_set_frame_type(sc, mode);
-
- sc->p.frame_type = mode;
-}
-
-static void t3e3_set_loopback(struct channel *sc, u32 mode)
-{
- u32 tx, rx;
-
- if (sc->p.loopback == mode)
- return;
-
- tx = sc->p.transmitter_on;
- rx = sc->p.receiver_on;
- if (tx == SBE_2T3E3_ON)
- dc_transmitter_onoff(sc, SBE_2T3E3_OFF);
- if (rx == SBE_2T3E3_ON)
- dc_receiver_onoff(sc, SBE_2T3E3_OFF);
-
- /* stop current loopback if any exists */
- switch (sc->p.loopback) {
- case SBE_2T3E3_LOOPBACK_NONE:
- break;
- case SBE_2T3E3_LOOPBACK_ETHERNET:
- dc_set_loopback(sc, SBE_2T3E3_21143_VAL_LOOPBACK_OFF);
- break;
- case SBE_2T3E3_LOOPBACK_FRAMER:
- exar7250_set_loopback(sc, SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF);
- break;
- case SBE_2T3E3_LOOPBACK_LIU_DIGITAL:
- case SBE_2T3E3_LOOPBACK_LIU_ANALOG:
- case SBE_2T3E3_LOOPBACK_LIU_REMOTE:
- exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_OFF);
- break;
- default:
- return;
- }
-
- switch (mode) {
- case SBE_2T3E3_LOOPBACK_NONE:
- break;
- case SBE_2T3E3_LOOPBACK_ETHERNET:
- dc_set_loopback(sc, SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL);
- break;
- case SBE_2T3E3_LOOPBACK_FRAMER:
- exar7250_set_loopback(sc, SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON);
- break;
- case SBE_2T3E3_LOOPBACK_LIU_DIGITAL:
- exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL);
- break;
- case SBE_2T3E3_LOOPBACK_LIU_ANALOG:
- exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG);
- break;
- case SBE_2T3E3_LOOPBACK_LIU_REMOTE:
- exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE);
- break;
- default:
- return;
- }
-
- sc->p.loopback = mode;
-
- if (tx == SBE_2T3E3_ON)
- dc_transmitter_onoff(sc, SBE_2T3E3_ON);
- if (rx == SBE_2T3E3_ON)
- dc_receiver_onoff(sc, SBE_2T3E3_ON);
-}
-
-
-static void t3e3_reg_read(struct channel *sc, u32 *reg, u32 *val)
-{
- u32 i;
-
- *val = 0;
-
- switch (reg[0]) {
- case SBE_2T3E3_CHIP_21143:
- if (!(reg[1] & 7))
- *val = dc_read(sc->addr, reg[1] / 8);
- break;
- case SBE_2T3E3_CHIP_CPLD:
- for (i = 0; i < SBE_2T3E3_CPLD_REG_MAX; i++)
- if (cpld_reg_map[i][sc->h.slot] == reg[1]) {
- *val = cpld_read(sc, i);
- break;
- }
- break;
- case SBE_2T3E3_CHIP_FRAMER:
- for (i = 0; i < SBE_2T3E3_FRAMER_REG_MAX; i++)
- if (t3e3_framer_reg_map[i] == reg[1]) {
- *val = exar7250_read(sc, i);
- break;
- }
- break;
- case SBE_2T3E3_CHIP_LIU:
- for (i = 0; i < SBE_2T3E3_LIU_REG_MAX; i++)
- if (t3e3_liu_reg_map[i] == reg[1]) {
- *val = exar7300_read(sc, i);
- break;
- }
- break;
- default:
- break;
- }
-}
-
-static void t3e3_reg_write(struct channel *sc, u32 *reg)
-{
- u32 i;
-
- switch (reg[0]) {
- case SBE_2T3E3_CHIP_21143:
- dc_write(sc->addr, reg[1], reg[2]);
- break;
- case SBE_2T3E3_CHIP_CPLD:
- for (i = 0; i < SBE_2T3E3_CPLD_REG_MAX; i++)
- if (cpld_reg_map[i][sc->h.slot] == reg[1]) {
- cpld_write(sc, i, reg[2]);
- break;
- }
- break;
- case SBE_2T3E3_CHIP_FRAMER:
- for (i = 0; i < SBE_2T3E3_FRAMER_REG_MAX; i++)
- if (t3e3_framer_reg_map[i] == reg[1]) {
- exar7250_write(sc, i, reg[2]);
- break;
- }
- break;
- case SBE_2T3E3_CHIP_LIU:
- for (i = 0; i < SBE_2T3E3_LIU_REG_MAX; i++)
- if (t3e3_liu_reg_map[i] == reg[1]) {
- exar7300_write(sc, i, reg[2]);
- break;
- }
- break;
- }
-}
-
-static void t3e3_port_get(struct channel *sc, struct t3e3_param *param)
-{
- memcpy(param, &(sc->p), sizeof(struct t3e3_param));
-}
-
-static void t3e3_port_set(struct channel *sc, struct t3e3_param *param)
-{
- if (param->frame_mode != 0xff)
- cpld_set_frame_mode(sc, param->frame_mode);
-
- if (param->fractional_mode != 0xff)
- cpld_set_fractional_mode(sc, param->fractional_mode,
- param->bandwidth_start,
- param->bandwidth_stop);
-
- if (param->pad_count != 0xff)
- cpld_set_pad_count(sc, param->pad_count);
-
- if (param->crc != 0xff)
- cpld_set_crc(sc, param->crc);
-
- if (param->receiver_on != 0xff)
- dc_receiver_onoff(sc, param->receiver_on);
-
- if (param->transmitter_on != 0xff)
- dc_transmitter_onoff(sc, param->transmitter_on);
-
- if (param->frame_type != 0xff)
- t3e3_set_frame_type(sc, param->frame_type);
-
- if (param->panel != 0xff)
- cpld_select_panel(sc, param->panel);
-
- if (param->line_build_out != 0xff)
- exar7300_line_build_out_onoff(sc, param->line_build_out);
-
- if (param->receive_equalization != 0xff)
- exar7300_receive_equalization_onoff(sc, param->receive_equalization);
-
- if (param->transmit_all_ones != 0xff)
- exar7300_transmit_all_ones_onoff(sc, param->transmit_all_ones);
-
- if (param->loopback != 0xff)
- t3e3_set_loopback(sc, param->loopback);
-
- if (param->clock_source != 0xff)
- cpld_set_clock(sc, param->clock_source);
-
- if (param->scrambler != 0xff)
- cpld_set_scrambler(sc, param->scrambler);
-}
-
-static void t3e3_port_get_stats(struct channel *sc, struct t3e3_stats *stats)
-{
- u32 result;
-
- sc->s.LOC = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL)
- & SBE_2T3E3_FRAMER_VAL_LOSS_OF_CLOCK_STATUS ? 1 : 0;
-
- switch (sc->p.frame_type) {
- case SBE_2T3E3_FRAME_TYPE_E3_G751:
- case SBE_2T3E3_FRAME_TYPE_E3_G832:
- result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
- sc->s.LOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOF ? 1 : 0;
- sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
-
- cpld_LOS_update(sc);
-
- sc->s.AIS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_AIS ? 1 : 0;
- sc->s.FERF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_FERF ? 1 : 0;
- break;
-
- case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
- case SBE_2T3E3_FRAME_TYPE_T3_M13:
- result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
- sc->s.AIS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_AIS ? 1 : 0;
-
- cpld_LOS_update(sc);
-
- sc->s.IDLE = result & SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE ? 1 : 0;
- sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
-
- result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_STATUS);
- sc->s.FERF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_FERF ? 1 : 0;
- sc->s.AIC = result & SBE_2T3E3_FRAMER_VAL_T3_RX_AIC ? 1 : 0;
- sc->s.FEBE_code = result & SBE_2T3E3_FRAMER_VAL_T3_RX_FEBE;
-
- sc->s.FEAC = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC);
- break;
-
- default:
- break;
- }
-
- result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_MSB) << 8;
- result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
- sc->s.LCV += result;
-
- result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB) << 8;
- result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
- sc->s.FRAMING_BIT += result;
-
- result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_MSB) << 8;
- result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
- sc->s.PARITY_ERROR += result;
-
- result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_MSB) << 8;
- result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
- sc->s.FEBE_count += result;
-
- result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_MSB) << 8;
- result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
- sc->s.CP_BIT += result;
-
- memcpy(stats, &(sc->s), sizeof(struct t3e3_stats));
-}
-
-static void t3e3_port_del_stats(struct channel *sc)
-{
- memset(&(sc->s), 0, sizeof(struct t3e3_stats));
-}
-
-void t3e3_if_config(struct channel *sc, u32 cmd, char *set,
- struct t3e3_resp *ret, int *rlen)
-{
- struct t3e3_param *param = (struct t3e3_param *)set;
- u32 *data = (u32 *)set;
-
- /* turn off all interrupt */
- /* cpld_stop_intr(sc); */
-
- switch (cmd) {
- case SBE_2T3E3_PORT_GET:
- t3e3_port_get(sc, &(ret->u.param));
- *rlen = sizeof(ret->u.param);
- break;
- case SBE_2T3E3_PORT_SET:
- t3e3_port_set(sc, param);
- *rlen = 0;
- break;
- case SBE_2T3E3_PORT_GET_STATS:
- t3e3_port_get_stats(sc, &(ret->u.stats));
- *rlen = sizeof(ret->u.stats);
- break;
- case SBE_2T3E3_PORT_DEL_STATS:
- t3e3_port_del_stats(sc);
- *rlen = 0;
- break;
- case SBE_2T3E3_PORT_READ_REGS:
- t3e3_reg_read(sc, data, &(ret->u.data));
- *rlen = sizeof(ret->u.data);
- break;
- case SBE_2T3E3_PORT_WRITE_REGS:
- t3e3_reg_write(sc, data);
- *rlen = 0;
- break;
- case SBE_2T3E3_LOG_LEVEL:
- *rlen = 0;
- break;
- default:
- *rlen = 0;
- break;
- }
-}
-
-void t3e3_sc_init(struct channel *sc)
-{
- memset(sc, 0, sizeof(*sc));
-
- sc->p.frame_mode = SBE_2T3E3_FRAME_MODE_HDLC;
- sc->p.fractional_mode = SBE_2T3E3_FRACTIONAL_MODE_NONE;
- sc->p.crc = SBE_2T3E3_CRC_32;
- sc->p.receiver_on = SBE_2T3E3_OFF;
- sc->p.transmitter_on = SBE_2T3E3_OFF;
- sc->p.frame_type = SBE_2T3E3_FRAME_TYPE_T3_CBIT;
- sc->p.panel = SBE_2T3E3_PANEL_FRONT;
- sc->p.line_build_out = SBE_2T3E3_OFF;
- sc->p.receive_equalization = SBE_2T3E3_OFF;
- sc->p.transmit_all_ones = SBE_2T3E3_OFF;
- sc->p.loopback = SBE_2T3E3_LOOPBACK_NONE;
- sc->p.clock_source = SBE_2T3E3_TIMING_LOCAL;
- sc->p.scrambler = SBE_2T3E3_SCRAMBLER_OFF;
- sc->p.pad_count = SBE_2T3E3_PAD_COUNT_1;
-}
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#ifndef CTRL_H
-#define CTRL_H
-
-#define SBE_2T3E3_OFF 0
-#define SBE_2T3E3_ON 1
-
-#define SBE_2T3E3_LED_NONE 0
-#define SBE_2T3E3_LED_GREEN 1
-#define SBE_2T3E3_LED_YELLOW 2
-
-#define SBE_2T3E3_CABLE_LENGTH_LESS_THAN_255_FEET 0
-#define SBE_2T3E3_CABLE_LENGTH_GREATER_THAN_255_FEET 1
-
-#define SBE_2T3E3_CRC_16 0
-#define SBE_2T3E3_CRC_32 1
-
-#define SBE_2T3E3_PANEL_FRONT 0
-#define SBE_2T3E3_PANEL_REAR 1
-
-#define SBE_2T3E3_FRAME_MODE_HDLC 0
-#define SBE_2T3E3_FRAME_MODE_TRANSPARENT 1
-#define SBE_2T3E3_FRAME_MODE_RAW 2
-
-#define SBE_2T3E3_FRAME_TYPE_E3_G751 0
-#define SBE_2T3E3_FRAME_TYPE_E3_G832 1
-#define SBE_2T3E3_FRAME_TYPE_T3_CBIT 2
-#define SBE_2T3E3_FRAME_TYPE_T3_M13 3
-
-#define SBE_2T3E3_FRACTIONAL_MODE_NONE 0
-#define SBE_2T3E3_FRACTIONAL_MODE_0 1
-#define SBE_2T3E3_FRACTIONAL_MODE_1 2
-#define SBE_2T3E3_FRACTIONAL_MODE_2 3
-
-#define SBE_2T3E3_SCRAMBLER_OFF 0
-#define SBE_2T3E3_SCRAMBLER_LARSCOM 1
-#define SBE_2T3E3_SCRAMBLER_ADC_KENTROX_DIGITAL 2
-
-#define SBE_2T3E3_TIMING_LOCAL 0
-#define SBE_2T3E3_TIMING_LOOP 1
-
-#define SBE_2T3E3_LOOPBACK_NONE 0
-#define SBE_2T3E3_LOOPBACK_ETHERNET 1
-#define SBE_2T3E3_LOOPBACK_FRAMER 2
-#define SBE_2T3E3_LOOPBACK_LIU_DIGITAL 3
-#define SBE_2T3E3_LOOPBACK_LIU_ANALOG 4
-#define SBE_2T3E3_LOOPBACK_LIU_REMOTE 5
-
-#define SBE_2T3E3_PAD_COUNT_1 1
-#define SBE_2T3E3_PAD_COUNT_2 2
-#define SBE_2T3E3_PAD_COUNT_3 3
-#define SBE_2T3E3_PAD_COUNT_4 4
-
-#define SBE_2T3E3_CHIP_21143 0
-#define SBE_2T3E3_CHIP_CPLD 1
-#define SBE_2T3E3_CHIP_FRAMER 2
-#define SBE_2T3E3_CHIP_LIU 3
-
-#define SBE_2T3E3_LOG_LEVEL_NONE 0
-#define SBE_2T3E3_LOG_LEVEL_ERROR 1
-#define SBE_2T3E3_LOG_LEVEL_WARNING 2
-#define SBE_2T3E3_LOG_LEVEL_INFO 3
-
-/* commands */
-#define SBE_2T3E3_PORT_GET 0
-#define SBE_2T3E3_PORT_SET 1
-#define SBE_2T3E3_PORT_GET_STATS 2
-#define SBE_2T3E3_PORT_DEL_STATS 3
-#define SBE_2T3E3_PORT_READ_REGS 4
-#define SBE_2T3E3_LOG_LEVEL 5
-#define SBE_2T3E3_PORT_WRITE_REGS 6
-
-#define NG_SBE_2T3E3_NODE_TYPE "sbe2T3E3"
-#define NG_SBE_2T3E3_COOKIE 0x03800891
-
-struct t3e3_param {
- u_int8_t frame_mode; /* FRAME_MODE_* */
- u_int8_t crc; /* CRC_* */
- u_int8_t receiver_on; /* ON/OFF */
- u_int8_t transmitter_on; /* ON/OFF */
- u_int8_t frame_type; /* FRAME_TYPE_* */
- u_int8_t panel; /* PANEL_* */
- u_int8_t line_build_out; /* ON/OFF */
- u_int8_t receive_equalization; /* ON/OFF */
- u_int8_t transmit_all_ones; /* ON/OFF */
- u_int8_t loopback; /* LOOPBACK_* */
- u_int8_t clock_source; /* TIMING_* */
- u_int8_t scrambler; /* SCRAMBLER_* */
- u_int8_t pad_count; /* PAD_COUNT_* */
- u_int8_t log_level; /* LOG_LEVEL_* - unused */
- u_int8_t fractional_mode; /* FRACTIONAL_MODE_* */
- u_int8_t bandwidth_start; /* 0-255 */
- u_int8_t bandwidth_stop; /* 0-255 */
-};
-
-struct t3e3_stats {
- u_int64_t in_bytes;
- u32 in_packets, in_dropped;
- u32 in_errors, in_error_desc, in_error_coll, in_error_drib,
- in_error_crc, in_error_mii;
- u_int64_t out_bytes;
- u32 out_packets, out_dropped;
- u32 out_errors, out_error_jab, out_error_lost_carr,
- out_error_no_carr, out_error_link_fail, out_error_underflow,
- out_error_dereferred;
- u_int8_t LOC, LOF, OOF, LOS, AIS, FERF, IDLE, AIC, FEAC;
- u_int16_t FEBE_code;
- u32 LCV, FRAMING_BIT, PARITY_ERROR, FEBE_count, CP_BIT;
-};
-
-
-struct t3e3_resp {
- union {
- struct t3e3_param param;
- struct t3e3_stats stats;
- u32 data;
- } u;
-};
-
-#endif /* CTRL_H */
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#include <linux/netdevice.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/io.h>
-#include "2t3e3.h"
-#include "ctrl.h"
-
-static int dc_init_descriptor_list(struct channel *sc);
-
-void dc_init(struct channel *sc)
-{
- u32 val;
-
- dc_stop(sc);
- /*dc_reset(sc);*/ /* do not want to reset here */
-
- /*
- * BUS_MODE (CSR0)
- */
- val = SBE_2T3E3_21143_VAL_READ_LINE_ENABLE |
- SBE_2T3E3_21143_VAL_READ_MULTIPLE_ENABLE |
- SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_200us |
- SBE_2T3E3_21143_VAL_BUS_ARBITRATION_RR;
-
- if (sc->h.command & 16)
- val |= SBE_2T3E3_21143_VAL_WRITE_AND_INVALIDATE_ENABLE;
-
- switch (sc->h.cache_size) {
- case 32:
- val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_32;
- break;
- case 16:
- val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_16;
- break;
- case 8:
- val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_8;
- break;
- default:
- break;
- }
-
- dc_write(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE, val);
-
- /* OPERATION_MODE (CSR6) */
- val = SBE_2T3E3_21143_VAL_RECEIVE_ALL |
- SBE_2T3E3_21143_VAL_MUST_BE_ONE |
- SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1 |
- SBE_2T3E3_21143_VAL_LOOPBACK_OFF |
- SBE_2T3E3_21143_VAL_PASS_ALL_MULTICAST |
- SBE_2T3E3_21143_VAL_PROMISCUOUS_MODE |
- SBE_2T3E3_21143_VAL_PASS_BAD_FRAMES;
- dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, val);
- if (sc->p.loopback == SBE_2T3E3_LOOPBACK_ETHERNET)
- sc->p.loopback = SBE_2T3E3_LOOPBACK_NONE;
-
- /*
- * GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL (CSR11)
- */
- val = SBE_2T3E3_21143_VAL_CYCLE_SIZE |
- SBE_2T3E3_21143_VAL_TRANSMIT_TIMER |
- SBE_2T3E3_21143_VAL_NUMBER_OF_TRANSMIT_PACKETS |
- SBE_2T3E3_21143_VAL_RECEIVE_TIMER |
- SBE_2T3E3_21143_VAL_NUMBER_OF_RECEIVE_PACKETS;
- dc_write(sc->addr, SBE_2T3E3_21143_REG_GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL, val);
-
- /* prepare descriptors and data for receive and transmit processes */
- if (dc_init_descriptor_list(sc) != 0)
- return;
-
- /* clear ethernet interrupts status */
- dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF);
-
- /* SIA mode registers */
- dc_set_output_port(sc);
-}
-
-void dc_start(struct channel *sc)
-{
- u32 val;
-
- if (!(sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP))
- return;
-
- dc_init(sc);
-
- /* get actual LOS and OOF status */
- switch (sc->p.frame_type) {
- case SBE_2T3E3_FRAME_TYPE_E3_G751:
- case SBE_2T3E3_FRAME_TYPE_E3_G832:
- val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
- dev_dbg(&sc->pdev->dev, "Start Framer Rx Status = %02X\n", val);
- sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
- break;
- case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
- case SBE_2T3E3_FRAME_TYPE_T3_M13:
- val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
- dev_dbg(&sc->pdev->dev, "Start Framer Rx Status = %02X\n", val);
- sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
- break;
- default:
- break;
- }
- cpld_LOS_update(sc);
-
- /* start receive and transmit processes */
- dc_transmitter_onoff(sc, SBE_2T3E3_ON);
- dc_receiver_onoff(sc, SBE_2T3E3_ON);
-
- /* start interrupts */
- dc_start_intr(sc);
-}
-
-#define MAX_INT_WAIT_CNT 12000
-void dc_stop(struct channel *sc)
-{
- int wcnt;
-
- /* stop receive and transmit processes */
- dc_receiver_onoff(sc, SBE_2T3E3_OFF);
- dc_transmitter_onoff(sc, SBE_2T3E3_OFF);
-
- /* turn off ethernet interrupts */
- dc_stop_intr(sc);
-
- /* wait to ensure the interrupts have been completed */
- for (wcnt = 0; wcnt < MAX_INT_WAIT_CNT; wcnt++) {
- udelay(5);
- if (!sc->interrupt_active)
- break;
- }
- if (wcnt >= MAX_INT_WAIT_CNT)
- dev_warn(&sc->pdev->dev, "SBE 2T3E3: Interrupt active too long\n");
-
- /* clear all receive/transmit data */
- dc_drop_descriptor_list(sc);
-}
-
-void dc_start_intr(struct channel *sc)
-{
- if (sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE && sc->s.OOF)
- return;
-
- if (sc->p.receiver_on || sc->p.transmitter_on) {
- if (!sc->ether.interrupt_enable_mask)
- dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF);
-
- sc->ether.interrupt_enable_mask =
- SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY_ENABLE |
- SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY_ENABLE |
- SBE_2T3E3_21143_VAL_RECEIVE_STOPPED_ENABLE |
- SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE_ENABLE |
- SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT_ENABLE |
- SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW_INTERRUPT_ENABLE |
- SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE_ENABLE |
- SBE_2T3E3_21143_VAL_TRANSMIT_STOPPED_ENABLE |
- SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT_ENABLE;
-
- dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE,
- sc->ether.interrupt_enable_mask);
- }
-}
-
-void dc_stop_intr(struct channel *sc)
-{
- sc->ether.interrupt_enable_mask = 0;
- dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0);
-}
-
-void dc_reset(struct channel *sc)
-{
- /* turn off ethernet interrupts */
- dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0);
- dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF);
-
- /* software reset */
- dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE,
- SBE_2T3E3_21143_VAL_SOFTWARE_RESET);
- udelay(4); /* 50 PCI cycles < 2us */
-
- /* clear hardware configuration */
- dc_write(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE, 0);
-
- /* clear software configuration */
- dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, 0);
-
- /* turn off SIA reset */
- dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY,
- SBE_2T3E3_21143_VAL_SIA_RESET);
- dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE, 0);
- dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT, 0);
-}
-
-
-void dc_receiver_onoff(struct channel *sc, u32 mode)
-{
- u32 i, state = 0;
-
- if (sc->p.receiver_on == mode)
- return;
-
- switch (mode) {
- case SBE_2T3E3_OFF:
- if (dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) &
- SBE_2T3E3_21143_VAL_RECEIVE_START) {
- dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_RECEIVE_START);
-
- for (i = 0; i < 16; i++) {
- state = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS) &
- SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STATE;
- if (state == SBE_2T3E3_21143_VAL_RX_STOPPED)
- break;
- udelay(5);
- }
- if (state != SBE_2T3E3_21143_VAL_RX_STOPPED)
- dev_warn(&sc->pdev->dev, "SBE 2T3E3: Rx failed to stop\n");
- else
- dev_info(&sc->pdev->dev, "SBE 2T3E3: Rx off\n");
- }
- break;
- case SBE_2T3E3_ON:
- dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_RECEIVE_START);
- udelay(100);
- dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND, 0xFFFFFFFF);
- break;
- default:
- return;
- }
-
- sc->p.receiver_on = mode;
-}
-
-void dc_transmitter_onoff(struct channel *sc, u32 mode)
-{
- u32 i, state = 0;
-
- if (sc->p.transmitter_on == mode)
- return;
-
- switch (mode) {
- case SBE_2T3E3_OFF:
- if (dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) &
- SBE_2T3E3_21143_VAL_TRANSMISSION_START) {
- dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_TRANSMISSION_START);
-
- for (i = 0; i < 16; i++) {
- state = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS) &
- SBE_2T3E3_21143_VAL_TRANSMISSION_PROCESS_STATE;
- if (state == SBE_2T3E3_21143_VAL_TX_STOPPED)
- break;
- udelay(5);
- }
- if (state != SBE_2T3E3_21143_VAL_TX_STOPPED)
- dev_warn(&sc->pdev->dev, "SBE 2T3E3: Tx failed to stop\n");
- }
- break;
- case SBE_2T3E3_ON:
- dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_TRANSMISSION_START);
- udelay(100);
- dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND, 0xFFFFFFFF);
- break;
- default:
- return;
- }
-
- sc->p.transmitter_on = mode;
-}
-
-
-
-void dc_set_loopback(struct channel *sc, u32 mode)
-{
- u32 val;
-
- switch (mode) {
- case SBE_2T3E3_21143_VAL_LOOPBACK_OFF:
- case SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL:
- break;
- default:
- return;
- }
-
- /* select loopback mode */
- val = dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) &
- ~SBE_2T3E3_21143_VAL_OPERATING_MODE;
- val |= mode;
- dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, val);
-
- if (mode == SBE_2T3E3_21143_VAL_LOOPBACK_OFF)
- dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE);
- else
- dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE);
-}
-
-static int dc_init_descriptor_list(struct channel *sc)
-{
- u32 i, j;
- struct sk_buff *m;
-
- if (sc->ether.rx_ring == NULL)
- sc->ether.rx_ring = kcalloc(SBE_2T3E3_RX_DESC_RING_SIZE,
- sizeof(struct t3e3_rx_desc), GFP_KERNEL);
- if (sc->ether.rx_ring == NULL)
- return -ENOMEM;
-
- if (sc->ether.tx_ring == NULL)
- sc->ether.tx_ring = kcalloc(SBE_2T3E3_TX_DESC_RING_SIZE,
- sizeof(struct t3e3_tx_desc), GFP_KERNEL);
- if (sc->ether.tx_ring == NULL) {
- kfree(sc->ether.rx_ring);
- sc->ether.rx_ring = NULL;
- return -ENOMEM;
- }
-
-
- /*
- * Receive ring
- */
- for (i = 0; i < SBE_2T3E3_RX_DESC_RING_SIZE; i++) {
- sc->ether.rx_ring[i].rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
- sc->ether.rx_ring[i].rdes1 =
- SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED | SBE_2T3E3_MTU;
-
- if (sc->ether.rx_data[i] == NULL) {
- m = dev_alloc_skb(MCLBYTES);
- if (!m) {
- for (j = 0; j < i; j++) {
- dev_kfree_skb_any(sc->ether.rx_data[j]);
- sc->ether.rx_data[j] = NULL;
- }
- kfree(sc->ether.rx_ring);
- sc->ether.rx_ring = NULL;
- kfree(sc->ether.tx_ring);
- sc->ether.tx_ring = NULL;
- dev_err(&sc->pdev->dev, "SBE 2T3E3: token_alloc err:"
- " no buffer space for RX ring\n");
- return -ENOBUFS;
- }
- sc->ether.rx_data[i] = m;
- }
- sc->ether.rx_ring[i].rdes2 = virt_to_phys(sc->ether.rx_data[i]->data);
-
- sc->ether.rx_ring[i].rdes3 = virt_to_phys(
- &sc->ether.rx_ring[(i + 1) % SBE_2T3E3_RX_DESC_RING_SIZE]);
- }
- sc->ether.rx_ring[SBE_2T3E3_RX_DESC_RING_SIZE - 1].rdes1 |=
- SBE_2T3E3_RX_DESC_END_OF_RING;
- sc->ether.rx_ring_current_read = 0;
-
- dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS,
- virt_to_phys(&sc->ether.rx_ring[0]));
-
- /*
- * Transmit ring
- */
- for (i = 0; i < SBE_2T3E3_TX_DESC_RING_SIZE; i++) {
- sc->ether.tx_ring[i].tdes0 = 0;
- sc->ether.tx_ring[i].tdes1 = SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED |
- SBE_2T3E3_TX_DESC_DISABLE_PADDING;
-
- sc->ether.tx_ring[i].tdes2 = 0;
- sc->ether.tx_data[i] = NULL;
-
- sc->ether.tx_ring[i].tdes3 = virt_to_phys(
- &sc->ether.tx_ring[(i + 1) % SBE_2T3E3_TX_DESC_RING_SIZE]);
- }
- sc->ether.tx_ring[SBE_2T3E3_TX_DESC_RING_SIZE - 1].tdes1 |=
- SBE_2T3E3_TX_DESC_END_OF_RING;
-
- dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS,
- virt_to_phys(&sc->ether.tx_ring[0]));
- sc->ether.tx_ring_current_read = 0;
- sc->ether.tx_ring_current_write = 0;
- sc->ether.tx_free_cnt = SBE_2T3E3_TX_DESC_RING_SIZE;
- spin_lock_init(&sc->ether.tx_lock);
-
- return 0;
-}
-
-void dc_clear_descriptor_list(struct channel *sc)
-{
- u32 i;
-
- /* clear CSR3 and CSR4 */
- dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS, 0);
- dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS, 0);
-
- /* free all data buffers on TX ring */
- for (i = 0; i < SBE_2T3E3_TX_DESC_RING_SIZE; i++) {
- if (sc->ether.tx_data[i] != NULL) {
- dev_kfree_skb_any(sc->ether.tx_data[i]);
- sc->ether.tx_data[i] = NULL;
- }
- }
-}
-
-void dc_drop_descriptor_list(struct channel *sc)
-{
- u32 i;
-
- dc_clear_descriptor_list(sc);
-
- /* free all data buffers on RX ring */
- for (i = 0; i < SBE_2T3E3_RX_DESC_RING_SIZE; i++) {
- if (sc->ether.rx_data[i] != NULL) {
- dev_kfree_skb_any(sc->ether.rx_data[i]);
- sc->ether.rx_data[i] = NULL;
- }
- }
-
- kfree(sc->ether.rx_ring);
- sc->ether.rx_ring = NULL;
- kfree(sc->ether.tx_ring);
- sc->ether.tx_ring = NULL;
-}
-
-
-void dc_set_output_port(struct channel *sc)
-{
- dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_PORT_SELECT);
-
- dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_STATUS, 0x00000301);
- dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY, 0);
- dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE, 0);
- dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT, 0x08000011);
-
- dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_100Mbs |
- SBE_2T3E3_21143_VAL_HEARTBEAT_DISABLE |
- SBE_2T3E3_21143_VAL_PORT_SELECT |
- SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE);
-}
-
-void dc_restart(struct channel *sc)
-{
- dev_warn(&sc->pdev->dev, "SBE 2T3E3: 21143 restart\n");
-
- dc_stop(sc);
- dc_reset(sc);
- dc_init(sc); /* stop + reset + init */
- dc_start(sc);
-}
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#include "2t3e3.h"
-#include "ctrl.h"
-
-void exar7250_init(struct channel *sc)
-{
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
- SBE_2T3E3_FRAMER_VAL_T3_CBIT |
- SBE_2T3E3_FRAMER_VAL_INTERRUPT_ENABLE_RESET |
- SBE_2T3E3_FRAMER_VAL_TIMING_ASYNCH_TXINCLK);
-
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
- SBE_2T3E3_FRAMER_VAL_DISABLE_TX_LOSS_OF_CLOCK |
- SBE_2T3E3_FRAMER_VAL_DISABLE_RX_LOSS_OF_CLOCK |
- SBE_2T3E3_FRAMER_VAL_AMI_LINE_CODE |
- SBE_2T3E3_FRAMER_VAL_RX_LINE_CLOCK_INVERT);
-
- exar7250_set_frame_type(sc, SBE_2T3E3_FRAME_TYPE_T3_CBIT);
-}
-
-void exar7250_set_frame_type(struct channel *sc, u32 type)
-{
- u32 val;
-
- switch (type) {
- case SBE_2T3E3_FRAME_TYPE_E3_G751:
- case SBE_2T3E3_FRAME_TYPE_E3_G832:
- case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
- case SBE_2T3E3_FRAME_TYPE_T3_M13:
- break;
- default:
- return;
- }
-
- exar7250_stop_intr(sc, type);
-
- val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE);
- val &= ~(SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE |
- SBE_2T3E3_FRAMER_VAL_T3_E3_SELECT |
- SBE_2T3E3_FRAMER_VAL_FRAME_FORMAT_SELECT);
- switch (type) {
- case SBE_2T3E3_FRAME_TYPE_E3_G751:
- val |= SBE_2T3E3_FRAMER_VAL_E3_G751;
- break;
- case SBE_2T3E3_FRAME_TYPE_E3_G832:
- val |= SBE_2T3E3_FRAMER_VAL_E3_G832;
- break;
- case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
- val |= SBE_2T3E3_FRAMER_VAL_T3_CBIT;
- break;
- case SBE_2T3E3_FRAME_TYPE_T3_M13:
- val |= SBE_2T3E3_FRAMER_VAL_T3_M13;
- break;
- default:
- return;
- }
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE, val);
- exar7250_start_intr(sc, type);
-}
-
-
-void exar7250_start_intr(struct channel *sc, u32 type)
-{
- u32 val;
-
- switch (type) {
- case SBE_2T3E3_FRAME_TYPE_E3_G751:
- case SBE_2T3E3_FRAME_TYPE_E3_G832:
- val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
-
- cpld_LOS_update(sc);
-
- sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1,
- SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
- SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE);
-
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
- break;
-
- case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
- case SBE_2T3E3_FRAME_TYPE_T3_M13:
- val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
-
- cpld_LOS_update(sc);
-
- sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
-
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE,
- SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
- SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE);
-
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
-
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL, 0);
- break;
-
- default:
- return;
- }
-
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE,
- SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE |
- SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE);
-}
-
-
-void exar7250_stop_intr(struct channel *sc, u32 type)
-{
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE, 0);
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
-
- switch (type) {
- case SBE_2T3E3_FRAME_TYPE_E3_G751:
- case SBE_2T3E3_FRAME_TYPE_E3_G832:
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1, 0);
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2, 0);
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL, 0);
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL);
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS, 0);
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS);
- break;
-
- case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
- case SBE_2T3E3_FRAME_TYPE_T3_M13:
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE, 0);
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS, 0);
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL, 0);
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL);
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS, 0);
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS);
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS, 0);
- exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS);
- break;
- }
-}
-
-
-
-
-void exar7250_unipolar_onoff(struct channel *sc, u32 mode)
-{
- switch (mode) {
- case SBE_2T3E3_OFF:
- exar7300_clear_bit(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
- SBE_2T3E3_FRAMER_VAL_UNIPOLAR);
- break;
- case SBE_2T3E3_ON:
- exar7300_set_bit(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
- SBE_2T3E3_FRAMER_VAL_UNIPOLAR);
- break;
- }
-}
-
-void exar7250_set_loopback(struct channel *sc, u32 mode)
-{
- switch (mode) {
- case SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF:
- exar7300_clear_bit(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
- SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE);
- break;
- case SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON:
- exar7300_set_bit(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
- SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE);
- break;
- }
-}
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#include "2t3e3.h"
-#include "ctrl.h"
-
-void exar7300_init(struct channel *sc)
-{
- exar7300_write(sc, SBE_2T3E3_LIU_REG_REG1, 0);
-
- /* enable line decodeer and encoder */
- exar7300_write(sc, SBE_2T3E3_LIU_REG_REG2, 0);
- exar7300_write(sc, SBE_2T3E3_LIU_REG_REG3, 0);
- exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4,
- SBE_2T3E3_LIU_VAL_T3_MODE_SELECT |
- SBE_2T3E3_LIU_VAL_LOOPBACK_OFF);
-}
-
-void exar7300_set_loopback(struct channel *sc, u32 mode)
-{
- u32 val;
-
- switch (mode) {
- case SBE_2T3E3_LIU_VAL_LOOPBACK_OFF:
- case SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE:
- case SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG:
- case SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL:
- break;
- default:
- return;
- }
-
- val = exar7300_read(sc, SBE_2T3E3_LIU_REG_REG4);
- val &= ~(SBE_2T3E3_LIU_VAL_LOCAL_LOOPBACK | SBE_2T3E3_LIU_VAL_REMOTE_LOOPBACK);
- val |= mode;
- exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4, val);
-}
-
-void exar7300_set_frame_type(struct channel *sc, u32 type)
-{
- u32 val;
-
- switch (type) {
- case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
- case SBE_2T3E3_FRAME_TYPE_T3_M13:
- case SBE_2T3E3_FRAME_TYPE_E3_G751:
- case SBE_2T3E3_FRAME_TYPE_E3_G832:
- break;
- default:
- return;
- }
-
- val = exar7300_read(sc, SBE_2T3E3_LIU_REG_REG4);
- val &= ~(SBE_2T3E3_LIU_VAL_T3_MODE_SELECT |
- SBE_2T3E3_LIU_VAL_E3_MODE_SELECT);
-
- switch (type) {
- case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
- case SBE_2T3E3_FRAME_TYPE_T3_M13:
- val |= SBE_2T3E3_LIU_VAL_T3_MODE_SELECT;
- break;
- case SBE_2T3E3_FRAME_TYPE_E3_G751:
- case SBE_2T3E3_FRAME_TYPE_E3_G832:
- val |= SBE_2T3E3_LIU_VAL_E3_MODE_SELECT;
- break;
- default:
- return;
- }
-
- exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4, val);
-}
-
-
-void exar7300_transmit_all_ones_onoff(struct channel *sc, u32 mode)
-{
- if (sc->p.transmit_all_ones == mode)
- return;
-
- switch (mode) {
- case SBE_2T3E3_ON:
- exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1,
- SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES);
- break;
- case SBE_2T3E3_OFF:
- exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1,
- SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES);
- break;
- default:
- return;
- }
-
- sc->p.transmit_all_ones = mode;
-}
-
-void exar7300_receive_equalization_onoff(struct channel *sc, u32 mode)
-{
- if (sc->p.receive_equalization == mode)
- return;
-
- switch (mode) {
- case SBE_2T3E3_OFF:
- exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG2,
- SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE);
- break;
- case SBE_2T3E3_ON:
- exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG2,
- SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE);
- break;
- default:
- return;
- }
-
- sc->p.receive_equalization = mode;
-}
-
-void exar7300_line_build_out_onoff(struct channel *sc, u32 mode)
-{
- if (sc->p.line_build_out == mode)
- return;
-
- switch (mode) {
- case SBE_2T3E3_OFF:
- exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1,
- SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT);
- exar7300_receive_equalization_onoff(sc, SBE_2T3E3_OFF);
- break;
- case SBE_2T3E3_ON:
- exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1,
- SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT);
- exar7300_receive_equalization_onoff(sc, SBE_2T3E3_ON);
- break;
- default:
- return;
- }
-
- sc->p.line_build_out = mode;
-}
-
-/* TODO - what about encoder in raw mode??? disable it too? */
-void exar7300_unipolar_onoff(struct channel *sc, u32 mode)
-{
- switch (mode) {
- case SBE_2T3E3_OFF:
- exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG3,
- SBE_2T3E3_LIU_VAL_DECODER_DISABLE);
- exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1,
- SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA);
- break;
- case SBE_2T3E3_ON:
- exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG3,
- SBE_2T3E3_LIU_VAL_DECODER_DISABLE);
- exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1,
- SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA);
- break;
- }
-}
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#include <linux/hdlc.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include "2t3e3.h"
-
-irqreturn_t t3e3_intr(int irq, void *dev_instance)
-{
- struct channel *sc = dev_to_priv(dev_instance);
- u32 val;
- irqreturn_t ret = IRQ_NONE;
-
- sc->interrupt_active = 1;
-
- val = cpld_read(sc, SBE_2T3E3_CPLD_REG_PICSR);
-
- if (val & SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_CHANGE) {
- dev_dbg(&sc->pdev->dev,
- "Rx LOS Chng Int r=%02x (LOS|OOF=%02x)\n",
- val, (sc->s.LOS << 4) | sc->s.OOF);
- cpld_LOS_update(sc);
- ret = IRQ_HANDLED;
- }
-
- if (val & SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ASSERTED) {
- dc_intr(sc);
- ret = IRQ_HANDLED;
- }
-
- if (val & SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ASSERTED) {
- exar7250_intr(sc);
- ret = IRQ_HANDLED;
- }
-
- /*
- we don't care about other interrupt sources (DMO, LOS, LCV) because
- they are handled by Framer too
- */
-
- sc->interrupt_active = 0;
- return ret;
-}
-
-void dc_intr(struct channel *sc)
-{
- u32 val;
-
- /* disable ethernet interrupts */
- /* grrr this clears interrupt summary bits !!! */
- dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0);
-
- while ((val = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS)) &
- (SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED |
- SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE |
- SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT |
- SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW |
- SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE |
- SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED |
- SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT)) {
- dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, val);
-
- dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Ethernet controller interrupt! (CSR5 = %08X)\n",
- val);
-
- if (val & (SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT |
- SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE |
- SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED)) {
- if (val & SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT)
- dev_dbg(&sc->pdev->dev,
- "Receive interrupt (LOS=%d, OOF=%d)\n",
- sc->s.LOS, sc->s.OOF);
- if (val & SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE)
- dev_dbg(&sc->pdev->dev,
- "Receive buffer unavailable\n");
- if (val & SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED)
- dev_dbg(&sc->pdev->dev,
- "Receive process stopped\n");
- dc_intr_rx(sc);
- }
-
- if (val & SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW) {
- dev_dbg(&sc->pdev->dev, "Transmit underflow\n");
- dc_intr_tx_underflow(sc);
- }
-
- if (val & (SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE |
- SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT |
- SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED)) {
- if (val & SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT)
- dev_dbg(&sc->pdev->dev, "Transmit interrupt\n");
- if (val & SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE)
- dev_dbg(&sc->pdev->dev,
- "Transmit buffer unavailable\n");
- if (val & SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED)
- dev_dbg(&sc->pdev->dev,
- "Transmit process stopped\n");
- dc_intr_tx(sc);
- }
- }
-
- /* enable ethernet interrupts */
- dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE,
- sc->ether.interrupt_enable_mask);
-}
-
-void dc_intr_rx(struct channel *sc)
-{
- u32 current_read;
- u32 error_mask, error;
- struct t3e3_rx_desc *current_desc;
- struct sk_buff *m, *m2;
- unsigned rcv_len;
-
- sc->rcv_count++; /* for the activity LED */
-
- current_read = sc->ether.rx_ring_current_read;
- dev_dbg(&sc->pdev->dev, "intr_rx current_read = %d\n", current_read);
-
- /* when ethernet loopback is set, ignore framer signals */
- if ((sc->p.loopback != SBE_2T3E3_LOOPBACK_ETHERNET) && sc->s.OOF) {
- while (!(sc->ether.rx_ring[current_read].rdes0 &
- SBE_2T3E3_RX_DESC_21143_OWN)) {
- current_desc = &sc->ether.rx_ring[current_read];
- current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING |
- SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED;
- current_desc->rdes1 |= SBE_2T3E3_MTU;
- current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
- current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE;
- }
- sc->ether.rx_ring_current_read = current_read;
- return;
- }
-
- while (!(sc->ether.rx_ring[current_read].rdes0 &
- SBE_2T3E3_RX_DESC_21143_OWN)) {
- current_desc = &sc->ether.rx_ring[current_read];
-
- dev_dbg(&sc->pdev->dev, "rdes0: %08X rdes1: %08X\n",
- current_desc->rdes0, current_desc->rdes1);
-
- m = sc->ether.rx_data[current_read];
- rcv_len = (current_desc->rdes0 & SBE_2T3E3_RX_DESC_FRAME_LENGTH) >>
- SBE_2T3E3_RX_DESC_FRAME_LENGTH_SHIFT;
-
- dev_dbg(&sc->pdev->dev, "mbuf was received (mbuf len = %d)\n",
- rcv_len);
-
- switch (sc->p.crc) {
- case SBE_2T3E3_CRC_16:
- rcv_len -= SBE_2T3E3_CRC16_LENGTH;
- break;
- case SBE_2T3E3_CRC_32:
- rcv_len -= SBE_2T3E3_CRC32_LENGTH;
- break;
- default:
- break;
- }
-
- if (current_desc->rdes0 & SBE_2T3E3_RX_DESC_LAST_DESC) {
-
- /* TODO: is collision possible? */
- error_mask = SBE_2T3E3_RX_DESC_DESC_ERROR |
- SBE_2T3E3_RX_DESC_COLLISION_SEEN |
- SBE_2T3E3_RX_DESC_DRIBBLING_BIT;
-
- switch (sc->p.frame_mode) {
- case SBE_2T3E3_FRAME_MODE_HDLC:
- error_mask |= SBE_2T3E3_RX_DESC_MII_ERROR;
- if (sc->p.crc == SBE_2T3E3_CRC_32)
- error_mask |= SBE_2T3E3_RX_DESC_CRC_ERROR;
- break;
- case SBE_2T3E3_FRAME_MODE_TRANSPARENT:
- case SBE_2T3E3_FRAME_MODE_RAW:
- break;
- default:
- error_mask = 0;
- }
-
- if (sc->s.LOS) {
- error_mask &= ~(SBE_2T3E3_RX_DESC_DRIBBLING_BIT |
- SBE_2T3E3_RX_DESC_MII_ERROR);
- }
-
- error = current_desc->rdes0 & error_mask;
- if (error) {
- sc->s.in_errors++;
- dev_dbg(&sc->pdev->dev,
- "error interrupt: NO_ERROR_MESSAGE = %d\n",
- sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES ? 1 : 0);
-
- current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING |
- SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED;
- current_desc->rdes1 |= SBE_2T3E3_MTU;
- current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
-
- if (error & SBE_2T3E3_RX_DESC_DESC_ERROR) {
- if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
- dev_err(&sc->pdev->dev,
- "SBE 2T3E3: descriptor error\n");
- sc->s.in_error_desc++;
- }
-
- if (error & SBE_2T3E3_RX_DESC_COLLISION_SEEN) {
- if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
- dev_err(&sc->pdev->dev,
- "SBE 2T3E3: collision seen\n");
- sc->s.in_error_coll++;
- } else {
- if (error & SBE_2T3E3_RX_DESC_DRIBBLING_BIT) {
- if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
- dev_err(&sc->pdev->dev,
- "SBE 2T3E3: dribbling bits error\n");
- sc->s.in_error_drib++;
- }
-
- if (error & SBE_2T3E3_RX_DESC_CRC_ERROR) {
- if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
- dev_err(&sc->pdev->dev,
- "SBE 2T3E3: crc error\n");
- sc->s.in_error_crc++;
- }
- }
-
- if (error & SBE_2T3E3_RX_DESC_MII_ERROR) {
- if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
- dev_err(&sc->pdev->dev, "SBE 2T3E3: mii error\n");
- sc->s.in_error_mii++;
- }
-
- current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE;
- sc->r.flags |= SBE_2T3E3_FLAG_NO_ERROR_MESSAGES;
- continue;
- }
- }
-
- current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING |
- SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED;
- current_desc->rdes1 |= SBE_2T3E3_MTU;
-
- if (rcv_len > 1600) {
- sc->s.in_errors++;
- sc->s.in_dropped++;
- if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
- dev_err(&sc->pdev->dev, "SBE 2T3E3: oversized rx: rdes0 = %08X\n",
- current_desc->rdes0);
- } else {
- m2 = dev_alloc_skb(MCLBYTES);
- if (m2 != NULL) {
- current_desc->rdes2 = virt_to_phys(m2->data);
- sc->ether.rx_data[current_read] = m2;
- sc->s.in_packets++;
- sc->s.in_bytes += rcv_len;
- m->dev = sc->dev;
- skb_put(m, rcv_len);
- skb_reset_mac_header(m);
- m->protocol = hdlc_type_trans(m, m->dev);
- netif_rx(m);
-
- /* good packet was received so we will show error messages again... */
- if (sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES) {
- dev_dbg(&sc->pdev->dev,
- "setting ERROR_MESSAGES->0\n");
- sc->r.flags &= ~SBE_2T3E3_FLAG_NO_ERROR_MESSAGES;
- }
-
- } else {
- sc->s.in_errors++;
- sc->s.in_dropped++;
- }
- }
- current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
- current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE;
- }
-
- sc->ether.rx_ring_current_read = current_read;
-
- dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND, 0xFFFFFFFF);
-}
-
-void dc_intr_tx(struct channel *sc)
-{
- u32 current_read, current_write;
- u32 last_segment, error;
- struct t3e3_tx_desc *current_desc;
-
- spin_lock(&sc->ether.tx_lock);
-
- current_read = sc->ether.tx_ring_current_read;
- current_write = sc->ether.tx_ring_current_write;
-
- while (current_read != current_write) {
- current_desc = &sc->ether.tx_ring[current_read];
-
- if (current_desc->tdes0 & SBE_2T3E3_RX_DESC_21143_OWN)
- break;
-
- dev_dbg(&sc->pdev->dev,
- "txeof: tdes0 = %08X tdes1 = %08X\n",
- current_desc->tdes0, current_desc->tdes1);
-
- error = current_desc->tdes0 & (SBE_2T3E3_TX_DESC_ERROR_SUMMARY |
- SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT |
- SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER |
- SBE_2T3E3_TX_DESC_NO_CARRIER |
- SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT |
- SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR |
- SBE_2T3E3_TX_DESC_DEFFERED);
-
- last_segment = current_desc->tdes1 & SBE_2T3E3_TX_DESC_LAST_SEGMENT;
-
- current_desc->tdes0 = 0;
- current_desc->tdes1 &= SBE_2T3E3_TX_DESC_END_OF_RING |
- SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED;
- current_desc->tdes2 = 0;
- sc->ether.tx_free_cnt++;
-
- if (last_segment != SBE_2T3E3_TX_DESC_LAST_SEGMENT) {
- current_read = (current_read + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
- continue;
- }
-
-
- if (sc->ether.tx_data[current_read]) {
- sc->s.out_packets++;
- sc->s.out_bytes += sc->ether.tx_data[current_read]->len;
- dev_kfree_skb_any(sc->ether.tx_data[current_read]);
- sc->ether.tx_data[current_read] = NULL;
- }
-
- if (error > 0) {
- sc->s.out_errors++;
-
- if (error & SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT) {
- dev_err(&sc->pdev->dev, "SBE 2T3E3: transmit jabber timeout\n");
- sc->s.out_error_jab++;
- }
-
- if (sc->p.loopback != SBE_2T3E3_LOOPBACK_ETHERNET) {
- if (error & SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER) {
- dev_err(&sc->pdev->dev, "SBE 2T3E3: loss of carrier\n");
- sc->s.out_error_lost_carr++;
- }
-
- if (error & SBE_2T3E3_TX_DESC_NO_CARRIER) {
- dev_err(&sc->pdev->dev, "SBE 2T3E3: no carrier\n");
- sc->s.out_error_no_carr++;
- }
- }
-
- if (error & SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT) {
- dev_err(&sc->pdev->dev, "SBE 2T3E3: link fail report\n");
- sc->s.out_error_link_fail++;
- }
-
- if (error & SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR) {
- dev_err(&sc->pdev->dev, "SBE 2T3E3:"
- " transmission underflow error\n");
- sc->s.out_error_underflow++;
- spin_unlock(&sc->ether.tx_lock);
-
- dc_restart(sc);
- return;
- }
-
- if (error & SBE_2T3E3_TX_DESC_DEFFERED) {
- dev_err(&sc->pdev->dev, "SBE 2T3E3: transmission deferred\n");
- sc->s.out_error_dereferred++;
- }
- }
-
- current_read = (current_read + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
- }
-
- sc->ether.tx_ring_current_read = current_read;
-
- /* Relieve flow control when the TX queue is drained at least half way */
- if (sc->ether.tx_full &&
- (sc->ether.tx_free_cnt >= (SBE_2T3E3_TX_DESC_RING_SIZE / 2))) {
- sc->ether.tx_full = 0;
- netif_wake_queue(sc->dev);
- }
- spin_unlock(&sc->ether.tx_lock);
-}
-
-
-void dc_intr_tx_underflow(struct channel *sc)
-{
- u32 val;
-
- dc_transmitter_onoff(sc, SBE_2T3E3_OFF);
-
- val = dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE);
- dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS);
-
- switch (val & SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS) {
- case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1:
- dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2);
- break;
- case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2:
- dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3);
- break;
- case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3:
- dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4);
- break;
- case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4:
- default:
- dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
- SBE_2T3E3_21143_VAL_STORE_AND_FORWARD);
- break;
- }
-
- dc_transmitter_onoff(sc, SBE_2T3E3_ON);
-}
-
-
-
-
-void exar7250_intr(struct channel *sc)
-{
- u32 status, old_OOF;
-
- old_OOF = sc->s.OOF;
-
- status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
- dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt! (REG[0x05] = %02X)\n", status);
-
- switch (sc->p.frame_type) {
- case SBE_2T3E3_FRAME_TYPE_E3_G751:
- case SBE_2T3E3_FRAME_TYPE_E3_G832:
- exar7250_E3_intr(sc, status);
- break;
-
- case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
- case SBE_2T3E3_FRAME_TYPE_T3_M13:
- exar7250_T3_intr(sc, status);
- break;
-
- default:
- break;
- }
-
- if (sc->s.OOF != old_OOF) {
- if (sc->s.OOF) {
- if (sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE) {
- dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Disabling eth interrupts\n");
- /* turn off ethernet interrupts */
- dc_stop_intr(sc);
- }
- } else if (sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP) {
- dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Enabling eth interrupts\n");
- /* start interrupts */
- sc->s.OOF = 1;
- dc_intr_rx(sc);
- sc->s.OOF = 0;
- if (sc->p.receiver_on) {
- dc_receiver_onoff(sc, SBE_2T3E3_OFF);
- dc_receiver_onoff(sc, SBE_2T3E3_ON);
- }
- dc_start_intr(sc);
- }
- }
-}
-
-
-void exar7250_T3_intr(struct channel *sc, u32 block_status)
-{
- u32 status, result;
-
- if (block_status & SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS) {
- status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
-
- if (status) {
- dev_dbg(&sc->pdev->dev,
- "Framer interrupt T3 RX (REG[0x13] = %02X)\n",
- status);
-
- result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
-
- cpld_LOS_update(sc);
-
- if (status & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_STATUS) {
- sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
- dev_dbg(&sc->pdev->dev,
- "Framer interrupt T3: OOF (%d)\n",
- sc->s.OOF);
- }
-
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE,
- SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
- SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE);
- }
-
- status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
- if (status) {
- dev_dbg(&sc->pdev->dev,
- "Framer interrupt T3 RX (REG[0x17] = %02X)\n",
- status);
- }
-
- status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL);
- if (status)
- dev_dbg(&sc->pdev->dev,
- "Framer interrupt T3 RX (REG[0x18] = %02X)\n",
- status);
- }
-
-
- if (block_status & SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS) {
- status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS);
- dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt T3 TX (REG[0x31] = %02X)\n",
- status);
-
- status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS);
- dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt T3 TX (REG[0x34] = %02X)\n",
- status);
- }
-}
-
-
-void exar7250_E3_intr(struct channel *sc, u32 block_status)
-{
- u32 status, result;
-
- if (block_status & SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS) {
- status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
-
- if (status) {
- dev_dbg(&sc->pdev->dev,
- "Framer interrupt E3 RX (REG[0x14] = %02X)\n",
- status);
-
- result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
-
- cpld_LOS_update(sc);
-
- if (status & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_STATUS) {
- sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
- dev_dbg(&sc->pdev->dev,
- "Framer interrupt E3: OOF (%d)\n",
- sc->s.OOF);
- }
-
- exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1,
- SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
- SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE
- );
- }
-
- status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
- if (status) {
- dev_dbg(&sc->pdev->dev,
- "Framer interrupt E3 RX (REG[0x15] = %02X)\n",
- status);
-
- }
-
- }
-
- if (block_status & SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS) {
- status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS);
- dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt E3 TX (REG[0x34] = %02X)\n",
- status);
- }
-}
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#include <linux/ip.h>
-#include "2t3e3.h"
-#include "ctrl.h"
-
-/* All access to registers done via the 21143 on port 0 must be
- * protected via the card->bootrom_lock. */
-
-/* private define to be used here only - must be protected by card->bootrom_lock */
-#define cpld_write_nolock(channel, reg, val) \
- bootrom_write((channel), CPLD_MAP_REG(reg, channel), val)
-
-u32 cpld_read(struct channel *channel, u32 reg)
-{
- unsigned long flags;
- u32 val;
-
- spin_lock_irqsave(&channel->card->bootrom_lock, flags);
- val = bootrom_read((channel), CPLD_MAP_REG(reg, channel));
- spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
- return val;
-}
-
-/****************************************
- * Access via BootROM port
- ****************************************/
-
-u32 bootrom_read(struct channel *channel, u32 reg)
-{
- unsigned long addr = channel->card->bootrom_addr;
- u32 result;
-
- /* select BootROM address */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS, reg & 0x3FFFF);
-
- /* select reading from BootROM */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_READ_OPERATION |
- SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT);
-
- udelay(2); /* 20 PCI cycles */
-
- /* read from BootROM */
- result = dc_read(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT) & 0xff;
-
- /* reset CSR9 */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
-
- return result;
-}
-
-void bootrom_write(struct channel *channel, u32 reg, u32 val)
-{
- unsigned long addr = channel->card->bootrom_addr;
-
- /* select BootROM address */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS, reg & 0x3FFFF);
-
- /* select writting to BootROM */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_WRITE_OPERATION |
- SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT |
- (val & 0xff));
-
- udelay(2); /* 20 PCI cycles */
-
- /* reset CSR9 */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
-}
-
-
-/****************************************
- * Access via Serial I/O port
- ****************************************/
-
-static u32 serialrom_read_bit(struct channel *channel)
-{
- unsigned long addr = channel->card->bootrom_addr;
- u32 bit;
-
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_READ_OPERATION |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock high */
-
- bit = (dc_read(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT) &
- SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_OUT) > 0 ? 1 : 0;
-
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_READ_OPERATION |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
-
- return bit;
-}
-
-static void serialrom_write_bit(struct channel *channel, u32 bit)
-{
- unsigned long addr = channel->card->bootrom_addr;
- u32 lastbit = -1;
-
- bit &= 1;
-
- if (bit != lastbit) {
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_WRITE_OPERATION |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT |
- (bit << 2)); /* clock low */
-
- lastbit = bit;
- }
-
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_WRITE_OPERATION |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT |
- (bit << 2)); /* clock high */
-
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_WRITE_OPERATION |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT |
- (bit << 2)); /* clock low */
-}
-
-/****************************************
- * Access to SerialROM (eeprom)
- ****************************************/
-
-u32 t3e3_eeprom_read_word(struct channel *channel, u32 address)
-{
- unsigned long addr = channel->card->bootrom_addr;
- u32 i, val;
- unsigned long flags;
-
- address &= 0x3f;
-
- spin_lock_irqsave(&channel->card->bootrom_lock, flags);
-
- /* select correct Serial Chip */
- cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT,
- SBE_2T3E3_CPLD_VAL_EEPROM_SELECT);
-
- /* select reading from Serial I/O Bus */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_READ_OPERATION |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
-
- /* select read operation */
- serialrom_write_bit(channel, 0);
- serialrom_write_bit(channel, 1);
- serialrom_write_bit(channel, 1);
- serialrom_write_bit(channel, 0);
-
- for (i = 0x20; i; i >>= 1)
- serialrom_write_bit(channel, address & i ? 1 : 0);
-
- val = 0;
- for (i = 0x8000; i; i >>= 1)
- val |= (serialrom_read_bit(channel) ? i : 0);
-
- /* Reset 21143's CSR9 */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_READ_OPERATION |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
-
- /* Unselect Serial Chip */
- cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0);
-
- spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
-
- return ntohs(val);
-}
-
-
-/****************************************
- * Access to Framer
- ****************************************/
-
-u32 exar7250_read(struct channel *channel, u32 reg)
-{
- u32 result;
- unsigned long flags;
-
- spin_lock_irqsave(&channel->card->bootrom_lock, flags);
-
- result = bootrom_read(channel, cpld_reg_map[SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS]
- [channel->h.slot] + (t3e3_framer_reg_map[reg] << 2));
-
- spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
-
- return result;
-}
-
-void exar7250_write(struct channel *channel, u32 reg, u32 val)
-{
- unsigned long flags;
-
- val &= 0xff;
- channel->framer_regs[reg] = val;
-
- spin_lock_irqsave(&channel->card->bootrom_lock, flags);
-
- bootrom_write(channel, cpld_reg_map[SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS]
- [channel->h.slot] + (t3e3_framer_reg_map[reg] << 2), val);
-
- spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
-}
-
-
-/****************************************
- * Access to LIU
- ****************************************/
-
-u32 exar7300_read(struct channel *channel, u32 reg)
-{
- unsigned long addr = channel->card->bootrom_addr, flags;
- u32 i, val;
-
- /* select correct Serial Chip */
-
- spin_lock_irqsave(&channel->card->bootrom_lock, flags);
-
- cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT,
- cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_SELECT][channel->h.slot]);
-
- /* select reading from Serial I/O Bus */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_READ_OPERATION |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
-
- /* select read operation */
- serialrom_write_bit(channel, 1);
-
- /* Exar7300 register address is 4 bit long */
- reg = t3e3_liu_reg_map[reg];
- for (i = 0; i < 4; i++, reg >>= 1) /* 4 bits of SerialROM address */
- serialrom_write_bit(channel, reg & 1);
- for (i = 0; i < 3; i++) /* remaining 3 bits of SerialROM address */
- serialrom_write_bit(channel, 0);
-
- val = 0; /* Exar7300 register value is 5 bit long */
- for (i = 0; i < 8; i++) /* 8 bits of SerialROM value */
- val += (serialrom_read_bit(channel) << i);
-
- /* Reset 21143's CSR9 */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_READ_OPERATION |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
-
- /* Unselect Serial Chip */
- cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0);
-
- spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
-
- return val;
-}
-
-void exar7300_write(struct channel *channel, u32 reg, u32 val)
-{
- unsigned long addr = channel->card->bootrom_addr, flags;
- u32 i;
-
- channel->liu_regs[reg] = val;
-
- /* select correct Serial Chip */
-
- spin_lock_irqsave(&channel->card->bootrom_lock, flags);
-
- cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT,
- cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_SELECT][channel->h.slot]);
-
- /* select writting to Serial I/O Bus */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_WRITE_OPERATION |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
-
- /* select write operation */
- serialrom_write_bit(channel, 0);
-
- /* Exar7300 register address is 4 bit long */
- reg = t3e3_liu_reg_map[reg];
- for (i = 0; i < 4; i++) { /* 4 bits */
- serialrom_write_bit(channel, reg & 1);
- reg >>= 1;
- }
- for (i = 0; i < 3; i++) /* remaining 3 bits of SerialROM address */
- serialrom_write_bit(channel, 0);
-
- /* Exar7300 register value is 5 bit long */
- for (i = 0; i < 5; i++) {
- serialrom_write_bit(channel, val & 1);
- val >>= 1;
- }
- for (i = 0; i < 3; i++) /* remaining 3 bits of SerialROM value */
- serialrom_write_bit(channel, 0);
-
- /* Reset 21143_CSR9 */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
- SBE_2T3E3_21143_VAL_WRITE_OPERATION |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
- SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
- dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
-
- /* Unselect Serial Chip */
- cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0);
-
- spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
-}
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include "2t3e3.h"
-
-void t3e3_init(struct channel *sc)
-{
- cpld_init(sc);
- dc_reset(sc);
- dc_init(sc);
- exar7250_init(sc);
- exar7300_init(sc);
-}
-
-int t3e3_if_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct channel *sc = dev_to_priv(dev);
- u32 current_write, last_write;
- unsigned long flags;
- struct sk_buff *skb2;
-
- if (skb == NULL) {
- sc->s.out_errors++;
- return 0;
- }
-
- if (sc->p.transmitter_on != SBE_2T3E3_ON) {
- sc->s.out_errors++;
- sc->s.out_dropped++;
- dev_kfree_skb_any(skb);
- return 0;
- }
-
- if (sc->s.OOF && sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE) {
- sc->s.out_dropped++;
- dev_kfree_skb_any(skb);
- return 0;
- }
-
- spin_lock_irqsave(&sc->ether.tx_lock, flags);
-
- current_write = sc->ether.tx_ring_current_write;
- for (skb2 = skb; skb2 != NULL; skb2 = NULL) {
- if (skb2->len) {
- if ((sc->ether.tx_ring[current_write].tdes1 &
- SBE_2T3E3_TX_DESC_BUFFER_1_SIZE) > 0)
- break;
- current_write = (current_write + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
- /*
- * Leave at least 1 tx desc free so that dc_intr_tx() can
- * identify empty list
- */
- if (current_write == sc->ether.tx_ring_current_read)
- break;
- }
- }
- if (skb2 != NULL) {
- netif_stop_queue(sc->dev);
- sc->ether.tx_full = 1;
- dev_dbg(&sc->pdev->dev, "SBE 2T3E3: out of descriptors\n");
- spin_unlock_irqrestore(&sc->ether.tx_lock, flags);
- return NETDEV_TX_BUSY;
- }
-
- current_write = last_write = sc->ether.tx_ring_current_write;
- dev_dbg(&sc->pdev->dev, "sending mbuf (current_write = %d)\n",
- current_write);
-
- for (skb2 = skb; skb2 != NULL; skb2 = NULL) {
- if (skb2->len) {
- dev_dbg(&sc->pdev->dev,
- "sending mbuf (len = %d, next = %p)\n",
- skb2->len, NULL);
-
- sc->ether.tx_free_cnt--;
- sc->ether.tx_ring[current_write].tdes0 = 0;
- sc->ether.tx_ring[current_write].tdes1 &=
- SBE_2T3E3_TX_DESC_END_OF_RING |
- SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED;
-/* DISABLE_PADDING sometimes gets lost somehow, hands off... */
- sc->ether.tx_ring[current_write].tdes1 |=
- SBE_2T3E3_TX_DESC_DISABLE_PADDING | skb2->len;
-
- if (current_write == sc->ether.tx_ring_current_write) {
- sc->ether.tx_ring[current_write].tdes1 |=
- SBE_2T3E3_TX_DESC_FIRST_SEGMENT;
- } else {
- sc->ether.tx_ring[current_write].tdes0 =
- SBE_2T3E3_TX_DESC_21143_OWN;
- }
-
- sc->ether.tx_ring[current_write].tdes2 = virt_to_phys(skb2->data);
- sc->ether.tx_data[current_write] = NULL;
-
- last_write = current_write;
- current_write = (current_write + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
- }
- }
-
- sc->ether.tx_data[last_write] = skb;
- sc->ether.tx_ring[last_write].tdes1 |=
- SBE_2T3E3_TX_DESC_LAST_SEGMENT |
- SBE_2T3E3_TX_DESC_INTERRUPT_ON_COMPLETION;
- sc->ether.tx_ring[sc->ether.tx_ring_current_write].tdes0 |=
- SBE_2T3E3_TX_DESC_21143_OWN;
- sc->ether.tx_ring_current_write = current_write;
-
- dev_dbg(&sc->pdev->dev, "txput: tdes0 = %08X tdes1 = %08X\n",
- sc->ether.tx_ring[last_write].tdes0,
- sc->ether.tx_ring[last_write].tdes1);
-
- dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND,
- 0xffffffff);
-
- spin_unlock_irqrestore(&sc->ether.tx_lock, flags);
- return 0;
-}
-
-
-void t3e3_read_card_serial_number(struct channel *sc)
-{
- u32 i;
-
- for (i = 0; i < 3; i++)
- sc->ether.card_serial_number[i] = t3e3_eeprom_read_word(sc, 10 + i);
-
- netdev_info(sc->dev, "SBE wanPMC-2T3E3 serial number: %04X%04X%04X\n",
- sc->ether.card_serial_number[0],
- sc->ether.card_serial_number[1],
- sc->ether.card_serial_number[2]);
-}
-
-/*
- bit 0 led1 (green)
- bit 1 led1 (yellow)
-
- bit 2 led2 (green)
- bit 3 led2 (yellow)
-
- bit 4 led3 (green)
- bit 5 led3 (yellow)
-
- bit 6 led4 (green)
- bit 7 led4 (yellow)
-*/
-
-void update_led(struct channel *sc, int blinker)
-{
- int leds;
- if (sc->s.LOS)
- leds = 0; /* led1 = off */
- else if (sc->s.OOF)
- leds = 2; /* led1 = yellow */
- else if ((blinker & 1) && sc->rcv_count) {
- leds = 0; /* led1 = off */
- sc->rcv_count = 0;
- } else
- leds = 1; /* led1 = green */
- cpld_write(sc, SBE_2T3E3_CPLD_REG_LEDR, leds);
- sc->leds = leds;
-}
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#include <linux/kernel.h>
-#include "2t3e3.h"
-
-const u32 cpld_reg_map[][2] = {
- { 0x0000, 0x0080 }, /* 0 - Port Control Register A (PCRA) */
- { 0x0004, 0x0084 }, /* 1 - Port Control Register B (PCRB) */
- { 0x0008, 0x0088 }, /* 2 - LCV Count Register (PLCR) */
- { 0x000c, 0x008c }, /* 3 - LCV Threshold register (PLTR) */
- { 0x0010, 0x0090 }, /* 4 - Payload Fill Register (PPFR) */
- { 0x0200, 0x0200 }, /* 5 - Board ID / FPGA Programming Status Register */
- { 0x0204, 0x0204 }, /* 6 - FPGA Version Register */
- { 0x0800, 0x1000 }, /* 7 - Framer Registers Base Address */
- { 0x2000, 0x2000 }, /* 8 - Serial Chip Select Register */
- { 0x2004, 0x2004 }, /* 9 - Static Reset Register */
- { 0x2008, 0x2008 }, /* 10 - Pulse Reset Register */
- { 0x200c, 0x200c }, /* 11 - FPGA Reconfiguration Register */
- { 0x2010, 0x2014 }, /* 12 - LED Register (LEDR) */
- { 0x2018, 0x201c }, /* 13 - LIU Control and Status Register (PISCR) */
- { 0x2020, 0x2024 }, /* 14 - Interrupt Enable Register (PIER) */
- { 0x0068, 0x00e8 }, /* 15 - Port Control Register C (PCRC) */
- { 0x006c, 0x00ec }, /* 16 - Port Bandwidth Start (PBWF) */
- { 0x0070, 0x00f0 }, /* 17 - Port Bandwidth Stop (PBWL) */
-};
-
-const u32 cpld_val_map[][2] = {
- { 0x01, 0x02 }, /* LIU1 / LIU2 select for Serial Chip Select */
- { 0x04, 0x08 }, /* DAC1 / DAC2 select for Serial Chip Select */
- { 0x00, 0x04 }, /* LOOP1 / LOOP2 - select of loop timing source */
- { 0x01, 0x02 } /* PORT1 / PORT2 - select LIU and Framer for reset */
-};
-
-const u32 t3e3_framer_reg_map[] = {
- 0x00, /* 0 - OPERATING_MODE */
- 0x01, /* 1 - IO_CONTROL */
- 0x04, /* 2 - BLOCK_INTERRUPT_ENABLE */
- 0x05, /* 3 - BLOCK_INTERRUPT_STATUS */
- 0x10, /* 4 - T3_RX_CONFIGURATION_STATUS, E3_RX_CONFIGURATION_STATUS_1 */
- 0x11, /* 5 - T3_RX_STATUS, E3_RX_CONFIGURATION_STATUS_2 */
- 0x12, /* 6 - T3_RX_INTERRUPT_ENABLE, E3_RX_INTERRUPT_ENABLE_1 */
- 0x13, /* 7 - T3_RX_INTERRUPT_STATUS, E3_RX_INTERRUPT_ENABLE_2 */
- 0x14, /* 8 - T3_RX_SYNC_DETECT_ENABLE, E3_RX_INTERRUPT_STATUS_1 */
- 0x15, /* 9 - E3_RX_INTERRUPT_STATUS_2 */
- 0x16, /* 10 - T3_RX_FEAC */
- 0x17, /* 11 - T3_RX_FEAC_INTERRUPT_ENABLE_STATUS */
- 0x18, /* 12 - T3_RX_LAPD_CONTROL, E3_RX_LAPD_CONTROL */
- 0x19, /* 13 - T3_RX_LAPD_STATUS, E3_RX_LAPD_STATUS */
- 0x1a, /* 14 - E3_RX_NR_BYTE, E3_RX_SERVICE_BITS */
- 0x1b, /* 15 - E3_RX_GC_BYTE */
- 0x30, /* 16 - T3_TX_CONFIGURATION, E3_TX_CONFIGURATION */
- 0x31, /* 17 - T3_TX_FEAC_CONFIGURATION_STATUS */
- 0x32, /* 18 - T3_TX_FEAC */
- 0x33, /* 19 - T3_TX_LAPD_CONFIGURATION, E3_TX_LAPD_CONFIGURATION */
- 0x34, /* 20 - T3_TX_LAPD_STATUS, E3_TX_LAPD_STATUS_INTERRUPT */
- 0x35, /* 21 - T3_TX_MBIT_MASK, E3_TX_GC_BYTE, E3_TX_SERVICE_BITS */
- 0x36, /* 22 - T3_TX_FBIT_MASK, E3_TX_MA_BYTE */
- 0x37, /* 23 - T3_TX_FBIT_MASK_2, E3_TX_NR_BYTE */
- 0x38, /* 24 - T3_TX_FBIT_MASK_3 */
- 0x48, /* 25 - E3_TX_FA1_ERROR_MASK, E3_TX_FAS_ERROR_MASK_UPPER */
- 0x49, /* 26 - E3_TX_FA2_ERROR_MASK, E3_TX_FAS_ERROR_MASK_LOWER */
- 0x4a, /* 27 - E3_TX_BIP8_MASK, E3_TX_BIP4_MASK */
- 0x50, /* 28 - PMON_LCV_EVENT_COUNT_MSB */
- 0x51, /* 29 - PMON_LCV_EVENT_COUNT_LSB */
- 0x52, /* 30 - PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB */
- 0x53, /* 31 - PMON_FRAMING_BIT_ERROR_EVENT_COUNT_LSB */
- 0x54, /* 32 - PMON_PARITY_ERROR_EVENT_COUNT_MSB */
- 0x55, /* 33 - PMON_PARITY_ERROR_EVENT_COUNT_LSB */
- 0x56, /* 34 - PMON_FEBE_EVENT_COUNT_MSB */
- 0x57, /* 35 - PMON_FEBE_EVENT_COUNT_LSB */
- 0x58, /* 36 - PMON_CP_BIT_ERROR_EVENT_COUNT_MSB */
- 0x59, /* 37 - PMON_CP_BIT_ERROR_EVENT_COUNT_LSB */
- 0x6c, /* 38 - PMON_HOLDING_REGISTER */
- 0x6d, /* 39 - ONE_SECOND_ERROR_STATUS */
- 0x6e, /* 40 - LCV_ONE_SECOND_ACCUMULATOR_MSB */
- 0x6f, /* 41 - LCV_ONE_SECOND_ACCUMULATOR_LSB */
- 0x70, /* 42 - FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_MSB */
- 0x71, /* 43 - FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_LSB */
- 0x72, /* 44 - FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_MSB */
- 0x73, /* 45 - FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_LSB */
- 0x80, /* 46 - LINE_INTERFACE_DRIVE */
- 0x81 /* 47 - LINE_INTERFACE_SCAN */
-};
-
-const u32 t3e3_liu_reg_map[] = {
- 0x00, /* REG0 */
- 0x01, /* REG1 */
- 0x02, /* REG2 */
- 0x03, /* REG3 */
- 0x04 /* REG4 */
-};
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/hdlc.h>
-#include <linux/if_arp.h>
-#include <linux/interrupt.h>
-#include "2t3e3.h"
-
-static void check_leds(unsigned long arg)
-{
- struct card *card = (struct card *)arg;
- struct channel *channel0 = &card->channels[0];
- static int blinker;
-
- update_led(channel0, ++blinker);
- if (has_two_ports(channel0->pdev))
- update_led(&card->channels[1], blinker);
-
- card->timer.expires = jiffies + HZ / 10;
- add_timer(&card->timer);
-}
-
-static void t3e3_remove_channel(struct channel *channel)
-{
- struct pci_dev *pdev = channel->pdev;
- struct net_device *dev = channel->dev;
-
- /* system hangs if board asserts irq while module is unloaded */
- cpld_stop_intr(channel);
- free_irq(dev->irq, dev);
- dc_drop_descriptor_list(channel);
- unregister_hdlc_device(dev);
- free_netdev(dev);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
-}
-
-static int t3e3_init_channel(struct channel *channel, struct pci_dev *pdev, struct card *card)
-{
- struct net_device *dev;
- unsigned int val;
- int err;
-
- err = pci_enable_device(pdev);
- if (err)
- return err;
-
- err = pci_request_regions(pdev, "SBE 2T3E3");
- if (err)
- goto disable;
-
- dev = alloc_hdlcdev(channel);
- if (!dev) {
- pr_err("Out of memory\n");
- err = -ENOMEM;
- goto free_regions;
- }
-
- t3e3_sc_init(channel);
- dev_to_priv(dev) = channel;
-
- channel->pdev = pdev;
- channel->dev = dev;
- channel->card = card;
- channel->addr = pci_resource_start(pdev, 0);
- if (pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P1)
- channel->h.slot = 1;
- else
- channel->h.slot = 0;
-
- err = setup_device(dev, channel);
- if (err)
- goto free_dev;
-
- pci_read_config_dword(channel->pdev, 0x40, &val); /* mask sleep mode */
- pci_write_config_dword(channel->pdev, 0x40, val & 0x3FFFFFFF);
-
- pci_read_config_byte(channel->pdev, PCI_CACHE_LINE_SIZE, &channel->h.cache_size);
- pci_read_config_dword(channel->pdev, PCI_COMMAND, &channel->h.command);
- t3e3_init(channel);
-
- err = request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev);
- if (err) {
- netdev_warn(channel->dev, "%s: could not get irq: %d\n",
- dev->name, dev->irq);
- goto unregister_dev;
- }
-
- pci_set_drvdata(pdev, channel);
- return 0;
-
-unregister_dev:
- unregister_hdlc_device(dev);
-free_dev:
- free_netdev(dev);
-free_regions:
- pci_release_regions(pdev);
-disable:
- pci_disable_device(pdev);
- return err;
-}
-
-static void t3e3_remove_card(struct pci_dev *pdev)
-{
- struct channel *channel0 = pci_get_drvdata(pdev);
- struct card *card = channel0->card;
-
- del_timer_sync(&card->timer);
- if (has_two_ports(channel0->pdev)) {
- t3e3_remove_channel(&card->channels[1]);
- pci_dev_put(card->channels[1].pdev);
- }
- t3e3_remove_channel(channel0);
- kfree(card);
-}
-
-static int t3e3_init_card(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- /* pdev points to channel #0 */
- struct pci_dev *pdev1 = NULL;
- struct card *card;
- int channels = 1, err;
-
- if (has_two_ports(pdev)) {
- while ((pdev1 = pci_get_subsys(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
- PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_2T3E3_P1,
- pdev1)))
- if (pdev1->bus == pdev->bus &&
- pdev1->devfn == pdev->devfn + 8 /* next device on the same bus */)
- break; /* found the second channel */
-
- if (!pdev1) {
- dev_err(&pdev->dev, "Can't find the second channel\n");
- return -EFAULT;
- }
- channels = 2;
- /* holds the reference for pdev1 */
- }
-
- card = kzalloc(sizeof(struct card) + channels * sizeof(struct channel),
- GFP_KERNEL);
- if (!card)
- return -ENOBUFS;
-
- spin_lock_init(&card->bootrom_lock);
- card->bootrom_addr = pci_resource_start(pdev, 0);
-
- err = t3e3_init_channel(&card->channels[0], pdev, card);
- if (err)
- goto free_card;
-
- if (channels == 2) {
- err = t3e3_init_channel(&card->channels[1], pdev1, card);
- if (err) {
- t3e3_remove_channel(&card->channels[0]);
- goto free_card;
- }
- }
-
- /* start LED timer */
- init_timer(&card->timer);
- card->timer.function = check_leds;
- card->timer.expires = jiffies + HZ / 10;
- card->timer.data = (unsigned long)card;
- add_timer(&card->timer);
- return 0;
-
-free_card:
- kfree(card);
- return err;
-}
-
-static struct pci_device_id t3e3_pci_tbl[] = {
- { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
- PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_T3E3, 0, 0, 0 },
- { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
- PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_2T3E3_P0, 0, 0, 0 },
- /* channel 1 will be initialized after channel 0 */
- { 0, }
-};
-
-static struct pci_driver t3e3_pci_driver = {
- .name = "SBE T3E3",
- .id_table = t3e3_pci_tbl,
- .probe = t3e3_init_card,
- .remove = t3e3_remove_card,
-};
-
-module_pci_driver(t3e3_pci_driver);
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, t3e3_pci_tbl);
+++ /dev/null
-/*
- * SBE 2T3E3 synchronous serial card driver for Linux
- *
- * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
- *
- * 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 code is based on a driver written by SBE Inc.
- */
-
-#include <linux/capability.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/hdlc.h>
-#include <linux/if_arp.h>
-#include <linux/interrupt.h>
-#include "2t3e3.h"
-
-static int t3e3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
- struct channel *sc = dev_to_priv(dev);
- int cmd_2t3e3, len, rlen;
- struct t3e3_param param;
- struct t3e3_resp resp;
- void __user *data = ifr->ifr_data + sizeof(cmd_2t3e3) + sizeof(len);
-
- if (cmd == SIOCWANDEV)
- return hdlc_ioctl(dev, ifr, cmd);
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (cmd != SIOCDEVPRIVATE + 15)
- return -EINVAL;
-
- if (copy_from_user(&cmd_2t3e3, ifr->ifr_data, sizeof(cmd_2t3e3)))
- return -EFAULT;
- if (copy_from_user(&len, ifr->ifr_data + sizeof(cmd_2t3e3), sizeof(len)))
- return -EFAULT;
-
- if (len > sizeof(param))
- return -EFAULT;
-
- if (len)
- if (copy_from_user(¶m, data, len))
- return -EFAULT;
-
- t3e3_if_config(sc, cmd_2t3e3, (char *)¶m, &resp, &rlen);
-
- if (rlen)
- if (copy_to_user(data, &resp, rlen))
- return -EFAULT;
-
- return 0;
-}
-
-static struct net_device_stats *t3e3_get_stats(struct net_device *dev)
-{
- struct net_device_stats *nstats = &dev->stats;
- struct channel *sc = dev_to_priv(dev);
- struct t3e3_stats *stats = &sc->s;
-
- memset(nstats, 0, sizeof(struct net_device_stats));
- nstats->rx_packets = stats->in_packets;
- nstats->tx_packets = stats->out_packets;
- nstats->rx_bytes = stats->in_bytes;
- nstats->tx_bytes = stats->out_bytes;
-
- nstats->rx_errors = stats->in_errors;
- nstats->tx_errors = stats->out_errors;
- nstats->rx_crc_errors = stats->in_error_crc;
-
-
- nstats->rx_dropped = stats->in_dropped;
- nstats->tx_dropped = stats->out_dropped;
- nstats->tx_carrier_errors = stats->out_error_lost_carr +
- stats->out_error_no_carr;
-
- return nstats;
-}
-
-static int t3e3_open(struct net_device *dev)
-{
- struct channel *sc = dev_to_priv(dev);
- int ret = hdlc_open(dev);
-
- if (ret)
- return ret;
-
- sc->r.flags |= SBE_2T3E3_FLAG_NETWORK_UP;
- dc_start(dev_to_priv(dev));
- netif_start_queue(dev);
- try_module_get(THIS_MODULE);
- return 0;
-}
-
-static int t3e3_close(struct net_device *dev)
-{
- struct channel *sc = dev_to_priv(dev);
- hdlc_close(dev);
- netif_stop_queue(dev);
- dc_stop(sc);
- sc->r.flags &= ~SBE_2T3E3_FLAG_NETWORK_UP;
- module_put(THIS_MODULE);
- return 0;
-}
-
-static int t3e3_attach(struct net_device *dev, unsigned short foo1,
- unsigned short foo2)
-{
- return 0;
-}
-
-static const struct net_device_ops t3e3_ops = {
- .ndo_open = t3e3_open,
- .ndo_stop = t3e3_close,
- .ndo_change_mtu = hdlc_change_mtu,
- .ndo_start_xmit = hdlc_start_xmit,
- .ndo_do_ioctl = t3e3_ioctl,
- .ndo_get_stats = t3e3_get_stats,
-};
-
-int setup_device(struct net_device *dev, struct channel *sc)
-{
- hdlc_device *hdlc = dev_to_hdlc(dev);
- int retval;
-
- dev->base_addr = pci_resource_start(sc->pdev, 0);
- dev->irq = sc->pdev->irq;
- dev->netdev_ops = &t3e3_ops;
- dev->tx_queue_len = 100;
- hdlc->xmit = t3e3_if_start_xmit;
- hdlc->attach = t3e3_attach;
- retval = register_hdlc_device(dev);
- if (retval) {
- dev_err(&sc->pdev->dev, "error registering HDLC device\n");
- return retval;
- }
- return 0;
-}
static void qt_close(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
- struct quatech_port *qt_port;
- struct quatech_port *port0;
- struct tty_struct *tty;
- int status;
- unsigned int index;
- status = 0;
-
- tty = tty_port_tty_get(&port->port);
- index = port->port_number;
-
- qt_port = qt_get_port_private(port);
- port0 = qt_get_port_private(serial->port[0]);
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+ unsigned int index = port->port_number;
+ struct quatech_port *qt_port = qt_get_port_private(port);
+ struct quatech_port *port0 = qt_get_port_private(serial->port[0]);
/* shutdown any bulk reads that might be going on */
if (serial->num_bulk_out)
tty_kref_put(tty);
/* Close uart channel */
- status = qt_close_channel(serial, index);
- if (status < 0)
+ if (qt_close_channel(serial, index) < 0)
dev_dbg(&port->dev, "%s - qt_close_channel failed.\n",
__func__);
if (I_IXOFF(tty) || I_IXON(tty)) {
unsigned char stop_char = STOP_CHAR(tty);
unsigned char start_char = START_CHAR(tty);
- status =
- box_set_sw_flow_ctrl(port->serial, index, stop_char,
- start_char);
+
+ status = box_set_sw_flow_ctrl(port->serial, index, stop_char,
+ start_char);
if (status < 0)
dev_dbg(&port->dev,
"box_set_sw_flow_ctrl (enabled) failed\n");
static int bypass_proc_create_dev_sd(struct bpctl_dev *pbp_device_block);
static int bypass_proc_remove_dev_sd(struct bpctl_dev *pbp_device_block);
-static int bp_proc_create(void);
static int is_bypass_fn(struct bpctl_dev *pbpctl_dev);
static int get_dev_idx_bsf(int bus, int slot, int func);
if (netif_carrier_ok(dev))
return NOTIFY_DONE;
- if (((dev_num = get_dev_idx(dev->ifindex)) == -1) ||
- (!(pbpctl_dev = &bpctl_dev_arr[dev_num])))
+ dev_num = get_dev_idx(dev->ifindex);
+ if (dev_num == -1)
+ return NOTIFY_DONE;
+
+ pbpctl_dev = &bpctl_dev_arr[dev_num];
+ if (!pbpctl_dev)
return NOTIFY_DONE;
if ((is_bypass_fn(pbpctl_dev)) == 1)
}
register_netdevice_notifier(&bp_notifier_block);
-#ifdef BP_PROC_SUPPORT
- {
- int i = 0;
- /* unsigned long flags; */
- /* rcu_read_lock(); */
- bp_proc_create();
- for (i = 0; i < device_num; i++) {
- if (bpctl_dev_arr[i].ifindex) {
- /* spin_lock_irqsave(&bpvm_lock, flags); */
- bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]);
- bypass_proc_create_dev_sd(&bpctl_dev_arr[i]);
- /* spin_unlock_irqrestore(&bpvm_lock, flags); */
- }
-
- }
- /* rcu_read_unlock(); */
- }
-#endif
-
return 0;
}
for (i = 0; i < device_num; i++) {
/* unsigned long flags; */
-#ifdef BP_PROC_SUPPORT
-/* spin_lock_irqsave(&bpvm_lock, flags);
- rcu_read_lock(); */
- bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]);
-/* spin_unlock_irqrestore(&bpvm_lock, flags);
- rcu_read_unlock(); */
-#endif
remove_bypass_wd_auto(&bpctl_dev_arr[i]);
bpctl_dev_arr[i].reset_time = 0;
static struct proc_dir_entry *bp_procfs_dir;
-static int bp_proc_create(void)
-{
- bp_procfs_dir = proc_mkdir(BP_PROC_DIR, init_net.proc_net);
- if (bp_procfs_dir == (struct proc_dir_entry *)0) {
- printk(KERN_DEBUG
- "Could not create procfs nicinfo directory %s\n",
- BP_PROC_DIR);
- return -1;
- }
- return 0;
-}
-
static int procfs_add(char *proc_name, const struct file_operations *fops,
struct bpctl_dev *dev)
{
while ((pdev = pci_get_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) {
dev = pci_get_drvdata(pdev);
- if (dev != NULL) {
- dev = pci_get_drvdata(pdev);
- if ((dev != NULL) && (dev->ifindex == if_index)) {
- if ((pdev->vendor == SILICOM_VID) &&
- (pdev->device >= SILICOM_BP_PID_MIN) &&
- (pdev->device <= SILICOM_BP_PID_MAX)) {
- goto send_cmd;
- }
+ if ((dev != NULL) && (dev->ifindex == if_index)) {
+ if ((pdev->vendor == SILICOM_VID) &&
+ (pdev->device >= SILICOM_BP_PID_MIN) &&
+ (pdev->device <= SILICOM_BP_PID_MAX)) {
+ goto send_cmd;
+ }
#if defined(BP_VENDOR_SUPPORT) && defined(ETHTOOL_GDRVINFO)
- else {
- struct ethtool_drvinfo info;
- const struct ethtool_ops *ops =
- dev->ethtool_ops;
- int k = 0;
-
- if (ops->get_drvinfo) {
- memset(&info, 0, sizeof(info));
- info.cmd = ETHTOOL_GDRVINFO;
- ops->get_drvinfo(dev, &info);
- for (; bp_desc_array[k]; k++)
- if (!
- (strcmp
- (bp_desc_array[k],
- info.driver)))
- goto send_cmd;
-
- }
+ else {
+ struct ethtool_drvinfo info;
+ const struct ethtool_ops *ops =
+ dev->ethtool_ops;
+ int k = 0;
+
+ if (ops->get_drvinfo) {
+ memset(&info, 0, sizeof(info));
+ info.cmd = ETHTOOL_GDRVINFO;
+ ops->get_drvinfo(dev, &info);
+ for (; bp_desc_array[k]; k++)
+ if (!(strcmp(bp_desc_array[k],
+ info.driver)))
+ goto send_cmd;
}
-#endif
- return -1;
+
}
+#endif
+ return -1;
}
}
send_cmd:
--- /dev/null
+config CRYPTO_SKEIN
+ bool "Skein digest algorithm"
+ depends on (X86 || UML_X86) && 64BIT
+ select CRYPTO_THREEFISH
+ select CRYPTO_HASH
+ help
+ Skein secure hash algorithm is one of 5 finalists from the NIST SHA3
+ competition.
+
+ Skein is optimized for modern, 64bit processors and is highly
+ customizable. See:
+
+ http://www.skein-hash.info/sites/default/files/skein1.3.pdf
+
+ for more information. This module depends on the threefish block
+ cipher module.
+
+config CRYPTO_THREEFISH
+ bool "Threefish tweakable block cipher"
+ depends on (X86 || UML_X86) && 64BIT
+ select CRYPTO_ALGAPI
+ help
+ Threefish cipher algorithm is the tweakable block cipher underneath
+ the Skein family of secure hash algorithms. Skein is one of 5
+ finalists from the NIST SHA3 competition.
+
+ Skein is optimized for modern, 64bit processors and is highly
+ customizable. See:
+
+ http://www.skein-hash.info/sites/default/files/skein1.3.pdf
+
+ for more information.
--- /dev/null
+#
+# Makefile for the skein secure hash algorithm
+#
+subdir-ccflags-y := -I$(src)/include/
+
+obj-$(CONFIG_CRYPTO_SKEIN) += skein.o \
+ skeinApi.o \
+ skein_block.o
+
+obj-$(CONFIG_CRYPTO_THREEFISH) += threefish1024Block.o \
+ threefish256Block.o \
+ threefish512Block.o \
+ threefishApi.o
--- /dev/null
+skein/threefish TODO
+
+ - rename camelcase vars
+ - rename camelcase functions
+ - rename files
+ - move macros into appropriate header files
+ - add / pass test vectors
+ - module support
+
+Please send patches to Jason Cooper <jason@lakedaemon.net> in addition to the
+staging tree mailinglist.
--- /dev/null
+#ifndef _SKEIN_H_
+#define _SKEIN_H_ 1
+/**************************************************************************
+**
+** Interface declarations and internal definitions for Skein hashing.
+**
+** Source code author: Doug Whiting, 2008.
+**
+** This algorithm and source code is released to the public domain.
+**
+***************************************************************************
+**
+** The following compile-time switches may be defined to control some
+** tradeoffs between speed, code size, error checking, and security.
+**
+** The "default" note explains what happens when the switch is not defined.
+**
+** SKEIN_DEBUG -- make callouts from inside Skein code
+** to examine/display intermediate values.
+** [default: no callouts (no overhead)]
+**
+** SKEIN_ERR_CHECK -- how error checking is handled inside Skein
+** code. If not defined, most error checking
+** is disabled (for performance). Otherwise,
+** the switch value is interpreted as:
+** 0: use assert() to flag errors
+** 1: return SKEIN_FAIL to flag errors
+**
+***************************************************************************/
+
+#ifndef RotL_64
+#define RotL_64(x, N) (((x) << (N)) | ((x) >> (64-(N))))
+#endif
+
+/* below two prototype assume we are handed aligned data */
+#define Skein_Put64_LSB_First(dst08, src64, bCnt) memcpy(dst08, src64, bCnt)
+#define Skein_Get64_LSB_First(dst64, src08, wCnt) memcpy(dst64, src08, 8*(wCnt))
+#define Skein_Swap64(w64) (w64)
+
+enum {
+ SKEIN_SUCCESS = 0, /* return codes from Skein calls */
+ SKEIN_FAIL = 1,
+ SKEIN_BAD_HASHLEN = 2
+};
+
+#define SKEIN_MODIFIER_WORDS (2) /* number of modifier (tweak) words */
+
+#define SKEIN_256_STATE_WORDS (4)
+#define SKEIN_512_STATE_WORDS (8)
+#define SKEIN1024_STATE_WORDS (16)
+#define SKEIN_MAX_STATE_WORDS (16)
+
+#define SKEIN_256_STATE_BYTES (8*SKEIN_256_STATE_WORDS)
+#define SKEIN_512_STATE_BYTES (8*SKEIN_512_STATE_WORDS)
+#define SKEIN1024_STATE_BYTES (8*SKEIN1024_STATE_WORDS)
+
+#define SKEIN_256_STATE_BITS (64*SKEIN_256_STATE_WORDS)
+#define SKEIN_512_STATE_BITS (64*SKEIN_512_STATE_WORDS)
+#define SKEIN1024_STATE_BITS (64*SKEIN1024_STATE_WORDS)
+
+#define SKEIN_256_BLOCK_BYTES (8*SKEIN_256_STATE_WORDS)
+#define SKEIN_512_BLOCK_BYTES (8*SKEIN_512_STATE_WORDS)
+#define SKEIN1024_BLOCK_BYTES (8*SKEIN1024_STATE_WORDS)
+
+struct skein_ctx_hdr {
+ size_t hashBitLen; /* size of hash result, in bits */
+ size_t bCnt; /* current byte count in buffer b[] */
+ u64 T[SKEIN_MODIFIER_WORDS]; /* tweak: T[0]=byte cnt, T[1]=flags */
+};
+
+struct skein_256_ctx { /* 256-bit Skein hash context structure */
+ struct skein_ctx_hdr h; /* common header context variables */
+ u64 X[SKEIN_256_STATE_WORDS]; /* chaining variables */
+ u8 b[SKEIN_256_BLOCK_BYTES]; /* partial block buf (8-byte aligned) */
+};
+
+struct skein_512_ctx { /* 512-bit Skein hash context structure */
+ struct skein_ctx_hdr h; /* common header context variables */
+ u64 X[SKEIN_512_STATE_WORDS]; /* chaining variables */
+ u8 b[SKEIN_512_BLOCK_BYTES]; /* partial block buf (8-byte aligned) */
+};
+
+struct skein1024_ctx { /* 1024-bit Skein hash context structure */
+ struct skein_ctx_hdr h; /* common header context variables */
+ u64 X[SKEIN1024_STATE_WORDS]; /* chaining variables */
+ u8 b[SKEIN1024_BLOCK_BYTES]; /* partial block buf (8-byte aligned) */
+};
+
+/* Skein APIs for (incremental) "straight hashing" */
+int Skein_256_Init(struct skein_256_ctx *ctx, size_t hashBitLen);
+int Skein_512_Init(struct skein_512_ctx *ctx, size_t hashBitLen);
+int Skein1024_Init(struct skein1024_ctx *ctx, size_t hashBitLen);
+
+int Skein_256_Update(struct skein_256_ctx *ctx, const u8 *msg,
+ size_t msgByteCnt);
+int Skein_512_Update(struct skein_512_ctx *ctx, const u8 *msg,
+ size_t msgByteCnt);
+int Skein1024_Update(struct skein1024_ctx *ctx, const u8 *msg,
+ size_t msgByteCnt);
+
+int Skein_256_Final(struct skein_256_ctx *ctx, u8 *hashVal);
+int Skein_512_Final(struct skein_512_ctx *ctx, u8 *hashVal);
+int Skein1024_Final(struct skein1024_ctx *ctx, u8 *hashVal);
+
+/*
+** Skein APIs for "extended" initialization: MAC keys, tree hashing.
+** After an InitExt() call, just use Update/Final calls as with Init().
+**
+** Notes: Same parameters as _Init() calls, plus treeInfo/key/keyBytes.
+** When keyBytes == 0 and treeInfo == SKEIN_SEQUENTIAL,
+** the results of InitExt() are identical to calling Init().
+** The function Init() may be called once to "precompute" the IV for
+** a given hashBitLen value, then by saving a copy of the context
+** the IV computation may be avoided in later calls.
+** Similarly, the function InitExt() may be called once per MAC key
+** to precompute the MAC IV, then a copy of the context saved and
+** reused for each new MAC computation.
+**/
+int Skein_256_InitExt(struct skein_256_ctx *ctx, size_t hashBitLen,
+ u64 treeInfo, const u8 *key, size_t keyBytes);
+int Skein_512_InitExt(struct skein_512_ctx *ctx, size_t hashBitLen,
+ u64 treeInfo, const u8 *key, size_t keyBytes);
+int Skein1024_InitExt(struct skein1024_ctx *ctx, size_t hashBitLen,
+ u64 treeInfo, const u8 *key, size_t keyBytes);
+
+/*
+** Skein APIs for MAC and tree hash:
+** Final_Pad: pad, do final block, but no OUTPUT type
+** Output: do just the output stage
+*/
+int Skein_256_Final_Pad(struct skein_256_ctx *ctx, u8 *hashVal);
+int Skein_512_Final_Pad(struct skein_512_ctx *ctx, u8 *hashVal);
+int Skein1024_Final_Pad(struct skein1024_ctx *ctx, u8 *hashVal);
+
+#ifndef SKEIN_TREE_HASH
+#define SKEIN_TREE_HASH (1)
+#endif
+#if SKEIN_TREE_HASH
+int Skein_256_Output(struct skein_256_ctx *ctx, u8 *hashVal);
+int Skein_512_Output(struct skein_512_ctx *ctx, u8 *hashVal);
+int Skein1024_Output(struct skein1024_ctx *ctx, u8 *hashVal);
+#endif
+
+/*****************************************************************
+** "Internal" Skein definitions
+** -- not needed for sequential hashing API, but will be
+** helpful for other uses of Skein (e.g., tree hash mode).
+** -- included here so that they can be shared between
+** reference and optimized code.
+******************************************************************/
+
+/* tweak word T[1]: bit field starting positions */
+#define SKEIN_T1_BIT(BIT) ((BIT) - 64) /* second word */
+
+#define SKEIN_T1_POS_TREE_LVL SKEIN_T1_BIT(112) /* 112..118 hash tree level */
+#define SKEIN_T1_POS_BIT_PAD SKEIN_T1_BIT(119) /* 119 part. final in byte */
+#define SKEIN_T1_POS_BLK_TYPE SKEIN_T1_BIT(120) /* 120..125 type field `*/
+#define SKEIN_T1_POS_FIRST SKEIN_T1_BIT(126) /* 126 first blk flag */
+#define SKEIN_T1_POS_FINAL SKEIN_T1_BIT(127) /* 127 final blk flag */
+
+/* tweak word T[1]: flag bit definition(s) */
+#define SKEIN_T1_FLAG_FIRST (((u64) 1) << SKEIN_T1_POS_FIRST)
+#define SKEIN_T1_FLAG_FINAL (((u64) 1) << SKEIN_T1_POS_FINAL)
+#define SKEIN_T1_FLAG_BIT_PAD (((u64) 1) << SKEIN_T1_POS_BIT_PAD)
+
+/* tweak word T[1]: tree level bit field mask */
+#define SKEIN_T1_TREE_LVL_MASK (((u64)0x7F) << SKEIN_T1_POS_TREE_LVL)
+#define SKEIN_T1_TREE_LEVEL(n) (((u64) (n)) << SKEIN_T1_POS_TREE_LVL)
+
+/* tweak word T[1]: block type field */
+#define SKEIN_BLK_TYPE_KEY (0) /* key, for MAC and KDF */
+#define SKEIN_BLK_TYPE_CFG (4) /* configuration block */
+#define SKEIN_BLK_TYPE_PERS (8) /* personalization string */
+#define SKEIN_BLK_TYPE_PK (12) /* pubkey (for digital sigs) */
+#define SKEIN_BLK_TYPE_KDF (16) /* key identifier for KDF */
+#define SKEIN_BLK_TYPE_NONCE (20) /* nonce for PRNG */
+#define SKEIN_BLK_TYPE_MSG (48) /* message processing */
+#define SKEIN_BLK_TYPE_OUT (63) /* output stage */
+#define SKEIN_BLK_TYPE_MASK (63) /* bit field mask */
+
+#define SKEIN_T1_BLK_TYPE(T) (((u64) (SKEIN_BLK_TYPE_##T)) << \
+ SKEIN_T1_POS_BLK_TYPE)
+#define SKEIN_T1_BLK_TYPE_KEY SKEIN_T1_BLK_TYPE(KEY) /* for MAC and KDF */
+#define SKEIN_T1_BLK_TYPE_CFG SKEIN_T1_BLK_TYPE(CFG) /* config block */
+#define SKEIN_T1_BLK_TYPE_PERS SKEIN_T1_BLK_TYPE(PERS) /* personalization */
+#define SKEIN_T1_BLK_TYPE_PK SKEIN_T1_BLK_TYPE(PK) /* pubkey (for sigs) */
+#define SKEIN_T1_BLK_TYPE_KDF SKEIN_T1_BLK_TYPE(KDF) /* key ident for KDF */
+#define SKEIN_T1_BLK_TYPE_NONCE SKEIN_T1_BLK_TYPE(NONCE)/* nonce for PRNG */
+#define SKEIN_T1_BLK_TYPE_MSG SKEIN_T1_BLK_TYPE(MSG) /* message processing */
+#define SKEIN_T1_BLK_TYPE_OUT SKEIN_T1_BLK_TYPE(OUT) /* output stage */
+#define SKEIN_T1_BLK_TYPE_MASK SKEIN_T1_BLK_TYPE(MASK) /* field bit mask */
+
+#define SKEIN_T1_BLK_TYPE_CFG_FINAL (SKEIN_T1_BLK_TYPE_CFG | \
+ SKEIN_T1_FLAG_FINAL)
+#define SKEIN_T1_BLK_TYPE_OUT_FINAL (SKEIN_T1_BLK_TYPE_OUT | \
+ SKEIN_T1_FLAG_FINAL)
+
+#define SKEIN_VERSION (1)
+
+#ifndef SKEIN_ID_STRING_LE /* allow compile-time personalization */
+#define SKEIN_ID_STRING_LE (0x33414853) /* "SHA3" (little-endian)*/
+#endif
+
+#define SKEIN_MK_64(hi32, lo32) ((lo32) + (((u64) (hi32)) << 32))
+#define SKEIN_SCHEMA_VER SKEIN_MK_64(SKEIN_VERSION, SKEIN_ID_STRING_LE)
+#define SKEIN_KS_PARITY SKEIN_MK_64(0x1BD11BDA, 0xA9FC1A22)
+
+#define SKEIN_CFG_STR_LEN (4*8)
+
+/* bit field definitions in config block treeInfo word */
+#define SKEIN_CFG_TREE_LEAF_SIZE_POS (0)
+#define SKEIN_CFG_TREE_NODE_SIZE_POS (8)
+#define SKEIN_CFG_TREE_MAX_LEVEL_POS (16)
+
+#define SKEIN_CFG_TREE_LEAF_SIZE_MSK (((u64)0xFF) << \
+ SKEIN_CFG_TREE_LEAF_SIZE_POS)
+#define SKEIN_CFG_TREE_NODE_SIZE_MSK (((u64)0xFF) << \
+ SKEIN_CFG_TREE_NODE_SIZE_POS)
+#define SKEIN_CFG_TREE_MAX_LEVEL_MSK (((u64)0xFF) << \
+ SKEIN_CFG_TREE_MAX_LEVEL_POS)
+
+#define SKEIN_CFG_TREE_INFO(leaf, node, maxLvl) \
+ ((((u64)(leaf)) << SKEIN_CFG_TREE_LEAF_SIZE_POS) | \
+ (((u64)(node)) << SKEIN_CFG_TREE_NODE_SIZE_POS) | \
+ (((u64)(maxLvl)) << SKEIN_CFG_TREE_MAX_LEVEL_POS))
+
+/* use as treeInfo in InitExt() call for sequential processing */
+#define SKEIN_CFG_TREE_INFO_SEQUENTIAL SKEIN_CFG_TREE_INFO(0, 0, 0)
+
+/*
+** Skein macros for getting/setting tweak words, etc.
+** These are useful for partial input bytes, hash tree init/update, etc.
+**/
+#define Skein_Get_Tweak(ctxPtr, TWK_NUM) ((ctxPtr)->h.T[TWK_NUM])
+#define Skein_Set_Tweak(ctxPtr, TWK_NUM, tVal) { \
+ (ctxPtr)->h.T[TWK_NUM] = (tVal); \
+ }
+
+#define Skein_Get_T0(ctxPtr) Skein_Get_Tweak(ctxPtr, 0)
+#define Skein_Get_T1(ctxPtr) Skein_Get_Tweak(ctxPtr, 1)
+#define Skein_Set_T0(ctxPtr, T0) Skein_Set_Tweak(ctxPtr, 0, T0)
+#define Skein_Set_T1(ctxPtr, T1) Skein_Set_Tweak(ctxPtr, 1, T1)
+
+/* set both tweak words at once */
+#define Skein_Set_T0_T1(ctxPtr, T0, T1) \
+ { \
+ Skein_Set_T0(ctxPtr, (T0)); \
+ Skein_Set_T1(ctxPtr, (T1)); \
+ }
+
+#define Skein_Set_Type(ctxPtr, BLK_TYPE) \
+ Skein_Set_T1(ctxPtr, SKEIN_T1_BLK_TYPE_##BLK_TYPE)
+
+/*
+ * setup for starting with a new type:
+ * h.T[0]=0; h.T[1] = NEW_TYPE; h.bCnt=0;
+ */
+#define Skein_Start_New_Type(ctxPtr, BLK_TYPE) { \
+ Skein_Set_T0_T1(ctxPtr, 0, SKEIN_T1_FLAG_FIRST | \
+ SKEIN_T1_BLK_TYPE_##BLK_TYPE); \
+ (ctxPtr)->h.bCnt = 0; \
+ }
+
+#define Skein_Clear_First_Flag(hdr) { \
+ (hdr).T[1] &= ~SKEIN_T1_FLAG_FIRST; \
+ }
+#define Skein_Set_Bit_Pad_Flag(hdr) { \
+ (hdr).T[1] |= SKEIN_T1_FLAG_BIT_PAD; \
+ }
+
+#define Skein_Set_Tree_Level(hdr, height) { \
+ (hdr).T[1] |= SKEIN_T1_TREE_LEVEL(height); \
+ }
+
+/*****************************************************************
+** "Internal" Skein definitions for debugging and error checking
+******************************************************************/
+#ifdef SKEIN_DEBUG /* examine/display intermediate values? */
+#include "skein_debug.h"
+#else /* default is no callouts */
+#define Skein_Show_Block(bits, ctx, X, blkPtr, wPtr, ksEvenPtr, ksOddPtr)
+#define Skein_Show_Round(bits, ctx, r, X)
+#define Skein_Show_R_Ptr(bits, ctx, r, X_ptr)
+#define Skein_Show_Final(bits, ctx, cnt, outPtr)
+#define Skein_Show_Key(bits, ctx, key, keyBytes)
+#endif
+
+#define Skein_Assert(x, retCode)/* ignore all Asserts, for performance */
+#define Skein_assert(x)
+
+/*****************************************************************
+** Skein block function constants (shared across Ref and Opt code)
+******************************************************************/
+enum {
+ /* Skein_256 round rotation constants */
+ R_256_0_0 = 14, R_256_0_1 = 16,
+ R_256_1_0 = 52, R_256_1_1 = 57,
+ R_256_2_0 = 23, R_256_2_1 = 40,
+ R_256_3_0 = 5, R_256_3_1 = 37,
+ R_256_4_0 = 25, R_256_4_1 = 33,
+ R_256_5_0 = 46, R_256_5_1 = 12,
+ R_256_6_0 = 58, R_256_6_1 = 22,
+ R_256_7_0 = 32, R_256_7_1 = 32,
+
+ /* Skein_512 round rotation constants */
+ R_512_0_0 = 46, R_512_0_1 = 36, R_512_0_2 = 19, R_512_0_3 = 37,
+ R_512_1_0 = 33, R_512_1_1 = 27, R_512_1_2 = 14, R_512_1_3 = 42,
+ R_512_2_0 = 17, R_512_2_1 = 49, R_512_2_2 = 36, R_512_2_3 = 39,
+ R_512_3_0 = 44, R_512_3_1 = 9, R_512_3_2 = 54, R_512_3_3 = 56,
+ R_512_4_0 = 39, R_512_4_1 = 30, R_512_4_2 = 34, R_512_4_3 = 24,
+ R_512_5_0 = 13, R_512_5_1 = 50, R_512_5_2 = 10, R_512_5_3 = 17,
+ R_512_6_0 = 25, R_512_6_1 = 29, R_512_6_2 = 39, R_512_6_3 = 43,
+ R_512_7_0 = 8, R_512_7_1 = 35, R_512_7_2 = 56, R_512_7_3 = 22,
+
+ /* Skein1024 round rotation constants */
+ R1024_0_0 = 24, R1024_0_1 = 13, R1024_0_2 = 8, R1024_0_3 = 47,
+ R1024_0_4 = 8, R1024_0_5 = 17, R1024_0_6 = 22, R1024_0_7 = 37,
+ R1024_1_0 = 38, R1024_1_1 = 19, R1024_1_2 = 10, R1024_1_3 = 55,
+ R1024_1_4 = 49, R1024_1_5 = 18, R1024_1_6 = 23, R1024_1_7 = 52,
+ R1024_2_0 = 33, R1024_2_1 = 4, R1024_2_2 = 51, R1024_2_3 = 13,
+ R1024_2_4 = 34, R1024_2_5 = 41, R1024_2_6 = 59, R1024_2_7 = 17,
+ R1024_3_0 = 5, R1024_3_1 = 20, R1024_3_2 = 48, R1024_3_3 = 41,
+ R1024_3_4 = 47, R1024_3_5 = 28, R1024_3_6 = 16, R1024_3_7 = 25,
+ R1024_4_0 = 41, R1024_4_1 = 9, R1024_4_2 = 37, R1024_4_3 = 31,
+ R1024_4_4 = 12, R1024_4_5 = 47, R1024_4_6 = 44, R1024_4_7 = 30,
+ R1024_5_0 = 16, R1024_5_1 = 34, R1024_5_2 = 56, R1024_5_3 = 51,
+ R1024_5_4 = 4, R1024_5_5 = 53, R1024_5_6 = 42, R1024_5_7 = 41,
+ R1024_6_0 = 31, R1024_6_1 = 44, R1024_6_2 = 47, R1024_6_3 = 46,
+ R1024_6_4 = 19, R1024_6_5 = 42, R1024_6_6 = 44, R1024_6_7 = 25,
+ R1024_7_0 = 9, R1024_7_1 = 48, R1024_7_2 = 35, R1024_7_3 = 52,
+ R1024_7_4 = 23, R1024_7_5 = 31, R1024_7_6 = 37, R1024_7_7 = 20
+};
+
+#ifndef SKEIN_ROUNDS
+#define SKEIN_256_ROUNDS_TOTAL (72) /* # rounds for diff block sizes */
+#define SKEIN_512_ROUNDS_TOTAL (72)
+#define SKEIN1024_ROUNDS_TOTAL (80)
+#else /* allow command-line define in range 8*(5..14) */
+#define SKEIN_256_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/100) + 5) % 10) + 5))
+#define SKEIN_512_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/10) + 5) % 10) + 5))
+#define SKEIN1024_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS) + 5) % 10) + 5))
+#endif
+
+#endif /* ifndef _SKEIN_H_ */
--- /dev/null
+/*
+Copyright (c) 2010 Werner Dittmann
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef SKEINAPI_H
+#define SKEINAPI_H
+
+/**
+ * @file skeinApi.h
+ * @brief A Skein API and its functions.
+ * @{
+ *
+ * This API and the functions that implement this API simplify the usage
+ * of Skein. The design and the way to use the functions follow the openSSL
+ * design but at the same time take care of some Skein specific behaviour
+ * and possibilities.
+ *
+ * The functions enable applications to create a normal Skein hashes and
+ * message authentication codes (MAC).
+ *
+ * Using these functions is simple and straight forward:
+ *
+ * @code
+ *
+ * #include <skeinApi.h>
+ *
+ * ...
+ * struct skein_ctx ctx; // a Skein hash or MAC context
+ *
+ * // prepare context, here for a Skein with a state size of 512 bits.
+ * skeinCtxPrepare(&ctx, Skein512);
+ *
+ * // Initialize the context to set the requested hash length in bits
+ * // here request a output hash size of 31 bits (Skein supports variable
+ * // output sizes even very strange sizes)
+ * skeinInit(&ctx, 31);
+ *
+ * // Now update Skein with any number of message bits. A function that
+ * // takes a number of bytes is also available.
+ * skeinUpdateBits(&ctx, message, msgLength);
+ *
+ * // Now get the result of the Skein hash. The output buffer must be
+ * // large enough to hold the request number of output bits. The application
+ * // may now extract the bits.
+ * skeinFinal(&ctx, result);
+ * ...
+ * @endcode
+ *
+ * An application may use @c skeinReset to reset a Skein context and use
+ * it for creation of another hash with the same Skein state size and output
+ * bit length. In this case the API implementation restores some internal
+ * internal state data and saves a full Skein initialization round.
+ *
+ * To create a MAC the application just uses @c skeinMacInit instead of
+ * @c skeinInit. All other functions calls remain the same.
+ *
+ */
+
+#include <linux/types.h>
+#include <skein.h>
+
+/**
+ * Which Skein size to use
+ */
+enum skein_size {
+ Skein256 = 256, /*!< Skein with 256 bit state */
+ Skein512 = 512, /*!< Skein with 512 bit state */
+ Skein1024 = 1024 /*!< Skein with 1024 bit state */
+};
+
+/**
+ * Context for Skein.
+ *
+ * This structure was setup with some know-how of the internal
+ * Skein structures, in particular ordering of header and size dependent
+ * variables. If Skein implementation changes this, then adapt these
+ * structures as well.
+ */
+struct skein_ctx {
+ u64 skeinSize;
+ u64 XSave[SKEIN_MAX_STATE_WORDS]; /* save area for state variables */
+ union {
+ struct skein_ctx_hdr h;
+ struct skein_256_ctx s256;
+ struct skein_512_ctx s512;
+ struct skein1024_ctx s1024;
+ } m;
+};
+
+/**
+ * Prepare a Skein context.
+ *
+ * An application must call this function before it can use the Skein
+ * context. The functions clears memory and initializes size dependent
+ * variables.
+ *
+ * @param ctx
+ * Pointer to a Skein context.
+ * @param size
+ * Which Skein size to use.
+ * @return
+ * SKEIN_SUCESS of SKEIN_FAIL
+ */
+int skeinCtxPrepare(struct skein_ctx *ctx, enum skein_size size);
+
+/**
+ * Initialize a Skein context.
+ *
+ * Initializes the context with this data and saves the resulting Skein
+ * state variables for further use.
+ *
+ * @param ctx
+ * Pointer to a Skein context.
+ * @param hashBitLen
+ * Number of MAC hash bits to compute
+ * @return
+ * SKEIN_SUCESS of SKEIN_FAIL
+ * @see skeinReset
+ */
+int skeinInit(struct skein_ctx *ctx, size_t hashBitLen);
+
+/**
+ * Resets a Skein context for further use.
+ *
+ * Restores the saved chaining variables to reset the Skein context.
+ * Thus applications can reuse the same setup to process several
+ * messages. This saves a complete Skein initialization cycle.
+ *
+ * @param ctx
+ * Pointer to a pre-initialized Skein MAC context
+ */
+void skeinReset(struct skein_ctx *ctx);
+
+/**
+ * Initializes a Skein context for MAC usage.
+ *
+ * Initializes the context with this data and saves the resulting Skein
+ * state variables for further use.
+ *
+ * Applications call the normal Skein functions to update the MAC and
+ * get the final result.
+ *
+ * @param ctx
+ * Pointer to an empty or preinitialized Skein MAC context
+ * @param key
+ * Pointer to key bytes or NULL
+ * @param keyLen
+ * Length of the key in bytes or zero
+ * @param hashBitLen
+ * Number of MAC hash bits to compute
+ * @return
+ * SKEIN_SUCESS of SKEIN_FAIL
+ */
+int skeinMacInit(struct skein_ctx *ctx, const u8 *key, size_t keyLen,
+ size_t hashBitLen);
+
+/**
+ * Update Skein with the next part of the message.
+ *
+ * @param ctx
+ * Pointer to initialized Skein context
+ * @param msg
+ * Pointer to the message.
+ * @param msgByteCnt
+ * Length of the message in @b bytes
+ * @return
+ * Success or error code.
+ */
+int skeinUpdate(struct skein_ctx *ctx, const u8 *msg,
+ size_t msgByteCnt);
+
+/**
+ * Update the hash with a message bit string.
+ *
+ * Skein can handle data not only as bytes but also as bit strings of
+ * arbitrary length (up to its maximum design size).
+ *
+ * @param ctx
+ * Pointer to initialized Skein context
+ * @param msg
+ * Pointer to the message.
+ * @param msgBitCnt
+ * Length of the message in @b bits.
+ */
+int skeinUpdateBits(struct skein_ctx *ctx, const u8 *msg,
+ size_t msgBitCnt);
+
+/**
+ * Finalize Skein and return the hash.
+ *
+ * Before an application can reuse a Skein setup the application must
+ * reset the Skein context.
+ *
+ * @param ctx
+ * Pointer to initialized Skein context
+ * @param hash
+ * Pointer to buffer that receives the hash. The buffer must be large
+ * enough to store @c hashBitLen bits.
+ * @return
+ * Success or error code.
+ * @see skeinReset
+ */
+int skeinFinal(struct skein_ctx *ctx, u8 *hash);
+
+/**
+ * @}
+ */
+#endif
--- /dev/null
+/***********************************************************************
+**
+** Implementation of the Skein hash function.
+**
+** Source code author: Doug Whiting, 2008.
+**
+** This algorithm and source code is released to the public domain.
+**
+************************************************************************/
+#ifndef _SKEIN_BLOCK_H_
+#define _SKEIN_BLOCK_H_
+
+#include <skein.h> /* get the Skein API definitions */
+
+void Skein_256_Process_Block(struct skein_256_ctx *ctx, const u8 *blkPtr,
+ size_t blkCnt, size_t byteCntAdd);
+void Skein_512_Process_Block(struct skein_512_ctx *ctx, const u8 *blkPtr,
+ size_t blkCnt, size_t byteCntAdd);
+void Skein1024_Process_Block(struct skein1024_ctx *ctx, const u8 *blkPtr,
+ size_t blkCnt, size_t byteCntAdd);
+
+#endif
--- /dev/null
+#ifndef _SKEIN_IV_H_
+#define _SKEIN_IV_H_
+
+#include <skein.h> /* get Skein macros and types */
+
+/*
+***************** Pre-computed Skein IVs *******************
+**
+** NOTE: these values are not "magic" constants, but
+** are generated using the Threefish block function.
+** They are pre-computed here only for speed; i.e., to
+** avoid the need for a Threefish call during Init().
+**
+** The IV for any fixed hash length may be pre-computed.
+** Only the most common values are included here.
+**
+************************************************************
+**/
+
+#define MK_64 SKEIN_MK_64
+
+/* blkSize = 256 bits. hashSize = 128 bits */
+const u64 SKEIN_256_IV_128[] = {
+ MK_64(0xE1111906, 0x964D7260),
+ MK_64(0x883DAAA7, 0x7C8D811C),
+ MK_64(0x10080DF4, 0x91960F7A),
+ MK_64(0xCCF7DDE5, 0xB45BC1C2)
+};
+
+/* blkSize = 256 bits. hashSize = 160 bits */
+const u64 SKEIN_256_IV_160[] = {
+ MK_64(0x14202314, 0x72825E98),
+ MK_64(0x2AC4E9A2, 0x5A77E590),
+ MK_64(0xD47A5856, 0x8838D63E),
+ MK_64(0x2DD2E496, 0x8586AB7D)
+};
+
+/* blkSize = 256 bits. hashSize = 224 bits */
+const u64 SKEIN_256_IV_224[] = {
+ MK_64(0xC6098A8C, 0x9AE5EA0B),
+ MK_64(0x876D5686, 0x08C5191C),
+ MK_64(0x99CB88D7, 0xD7F53884),
+ MK_64(0x384BDDB1, 0xAEDDB5DE)
+};
+
+/* blkSize = 256 bits. hashSize = 256 bits */
+const u64 SKEIN_256_IV_256[] = {
+ MK_64(0xFC9DA860, 0xD048B449),
+ MK_64(0x2FCA6647, 0x9FA7D833),
+ MK_64(0xB33BC389, 0x6656840F),
+ MK_64(0x6A54E920, 0xFDE8DA69)
+};
+
+/* blkSize = 512 bits. hashSize = 128 bits */
+const u64 SKEIN_512_IV_128[] = {
+ MK_64(0xA8BC7BF3, 0x6FBF9F52),
+ MK_64(0x1E9872CE, 0xBD1AF0AA),
+ MK_64(0x309B1790, 0xB32190D3),
+ MK_64(0xBCFBB854, 0x3F94805C),
+ MK_64(0x0DA61BCD, 0x6E31B11B),
+ MK_64(0x1A18EBEA, 0xD46A32E3),
+ MK_64(0xA2CC5B18, 0xCE84AA82),
+ MK_64(0x6982AB28, 0x9D46982D)
+};
+
+/* blkSize = 512 bits. hashSize = 160 bits */
+const u64 SKEIN_512_IV_160[] = {
+ MK_64(0x28B81A2A, 0xE013BD91),
+ MK_64(0xC2F11668, 0xB5BDF78F),
+ MK_64(0x1760D8F3, 0xF6A56F12),
+ MK_64(0x4FB74758, 0x8239904F),
+ MK_64(0x21EDE07F, 0x7EAF5056),
+ MK_64(0xD908922E, 0x63ED70B8),
+ MK_64(0xB8EC76FF, 0xECCB52FA),
+ MK_64(0x01A47BB8, 0xA3F27A6E)
+};
+
+/* blkSize = 512 bits. hashSize = 224 bits */
+const u64 SKEIN_512_IV_224[] = {
+ MK_64(0xCCD06162, 0x48677224),
+ MK_64(0xCBA65CF3, 0xA92339EF),
+ MK_64(0x8CCD69D6, 0x52FF4B64),
+ MK_64(0x398AED7B, 0x3AB890B4),
+ MK_64(0x0F59D1B1, 0x457D2BD0),
+ MK_64(0x6776FE65, 0x75D4EB3D),
+ MK_64(0x99FBC70E, 0x997413E9),
+ MK_64(0x9E2CFCCF, 0xE1C41EF7)
+};
+
+/* blkSize = 512 bits. hashSize = 256 bits */
+const u64 SKEIN_512_IV_256[] = {
+ MK_64(0xCCD044A1, 0x2FDB3E13),
+ MK_64(0xE8359030, 0x1A79A9EB),
+ MK_64(0x55AEA061, 0x4F816E6F),
+ MK_64(0x2A2767A4, 0xAE9B94DB),
+ MK_64(0xEC06025E, 0x74DD7683),
+ MK_64(0xE7A436CD, 0xC4746251),
+ MK_64(0xC36FBAF9, 0x393AD185),
+ MK_64(0x3EEDBA18, 0x33EDFC13)
+};
+
+/* blkSize = 512 bits. hashSize = 384 bits */
+const u64 SKEIN_512_IV_384[] = {
+ MK_64(0xA3F6C6BF, 0x3A75EF5F),
+ MK_64(0xB0FEF9CC, 0xFD84FAA4),
+ MK_64(0x9D77DD66, 0x3D770CFE),
+ MK_64(0xD798CBF3, 0xB468FDDA),
+ MK_64(0x1BC4A666, 0x8A0E4465),
+ MK_64(0x7ED7D434, 0xE5807407),
+ MK_64(0x548FC1AC, 0xD4EC44D6),
+ MK_64(0x266E1754, 0x6AA18FF8)
+};
+
+/* blkSize = 512 bits. hashSize = 512 bits */
+const u64 SKEIN_512_IV_512[] = {
+ MK_64(0x4903ADFF, 0x749C51CE),
+ MK_64(0x0D95DE39, 0x9746DF03),
+ MK_64(0x8FD19341, 0x27C79BCE),
+ MK_64(0x9A255629, 0xFF352CB1),
+ MK_64(0x5DB62599, 0xDF6CA7B0),
+ MK_64(0xEABE394C, 0xA9D5C3F4),
+ MK_64(0x991112C7, 0x1A75B523),
+ MK_64(0xAE18A40B, 0x660FCC33)
+};
+
+/* blkSize = 1024 bits. hashSize = 384 bits */
+const u64 SKEIN1024_IV_384[] = {
+ MK_64(0x5102B6B8, 0xC1894A35),
+ MK_64(0xFEEBC9E3, 0xFE8AF11A),
+ MK_64(0x0C807F06, 0xE32BED71),
+ MK_64(0x60C13A52, 0xB41A91F6),
+ MK_64(0x9716D35D, 0xD4917C38),
+ MK_64(0xE780DF12, 0x6FD31D3A),
+ MK_64(0x797846B6, 0xC898303A),
+ MK_64(0xB172C2A8, 0xB3572A3B),
+ MK_64(0xC9BC8203, 0xA6104A6C),
+ MK_64(0x65909338, 0xD75624F4),
+ MK_64(0x94BCC568, 0x4B3F81A0),
+ MK_64(0x3EBBF51E, 0x10ECFD46),
+ MK_64(0x2DF50F0B, 0xEEB08542),
+ MK_64(0x3B5A6530, 0x0DBC6516),
+ MK_64(0x484B9CD2, 0x167BBCE1),
+ MK_64(0x2D136947, 0xD4CBAFEA)
+};
+
+/* blkSize = 1024 bits. hashSize = 512 bits */
+const u64 SKEIN1024_IV_512[] = {
+ MK_64(0xCAEC0E5D, 0x7C1B1B18),
+ MK_64(0xA01B0E04, 0x5F03E802),
+ MK_64(0x33840451, 0xED912885),
+ MK_64(0x374AFB04, 0xEAEC2E1C),
+ MK_64(0xDF25A0E2, 0x813581F7),
+ MK_64(0xE4004093, 0x8B12F9D2),
+ MK_64(0xA662D539, 0xC2ED39B6),
+ MK_64(0xFA8B85CF, 0x45D8C75A),
+ MK_64(0x8316ED8E, 0x29EDE796),
+ MK_64(0x053289C0, 0x2E9F91B8),
+ MK_64(0xC3F8EF1D, 0x6D518B73),
+ MK_64(0xBDCEC3C4, 0xD5EF332E),
+ MK_64(0x549A7E52, 0x22974487),
+ MK_64(0x67070872, 0x5B749816),
+ MK_64(0xB9CD28FB, 0xF0581BD1),
+ MK_64(0x0E2940B8, 0x15804974)
+};
+
+/* blkSize = 1024 bits. hashSize = 1024 bits */
+const u64 SKEIN1024_IV_1024[] = {
+ MK_64(0xD593DA07, 0x41E72355),
+ MK_64(0x15B5E511, 0xAC73E00C),
+ MK_64(0x5180E5AE, 0xBAF2C4F0),
+ MK_64(0x03BD41D3, 0xFCBCAFAF),
+ MK_64(0x1CAEC6FD, 0x1983A898),
+ MK_64(0x6E510B8B, 0xCDD0589F),
+ MK_64(0x77E2BDFD, 0xC6394ADA),
+ MK_64(0xC11E1DB5, 0x24DCB0A3),
+ MK_64(0xD6D14AF9, 0xC6329AB5),
+ MK_64(0x6A9B0BFC, 0x6EB67E0D),
+ MK_64(0x9243C60D, 0xCCFF1332),
+ MK_64(0x1A1F1DDE, 0x743F02D4),
+ MK_64(0x0996753C, 0x10ED0BB8),
+ MK_64(0x6572DD22, 0xF2B4969A),
+ MK_64(0x61FD3062, 0xD00A579A),
+ MK_64(0x1DE0536E, 0x8682E539)
+};
+
+#endif /* _SKEIN_IV_H_ */
--- /dev/null
+
+#ifndef THREEFISHAPI_H
+#define THREEFISHAPI_H
+
+/**
+ * @file threefishApi.h
+ * @brief A Threefish cipher API and its functions.
+ * @{
+ *
+ * This API and the functions that implement this API simplify the usage
+ * of the Threefish cipher. The design and the way to use the functions
+ * follow the openSSL design but at the same time take care of some Threefish
+ * specific behaviour and possibilities.
+ *
+ * These are the low level functions that deal with Threefisch blocks only.
+ * Implementations for cipher modes such as ECB, CFB, or CBC may use these
+ * functions.
+ *
+@code
+ // Threefish cipher context data
+ struct threefish_key keyCtx;
+
+ // Initialize the context
+ threefishSetKey(&keyCtx, Threefish512, key, tweak);
+
+ // Encrypt
+ threefishEncryptBlockBytes(&keyCtx, input, cipher);
+@endcode
+ */
+
+#include <linux/types.h>
+#include <skein.h>
+
+#define KeyScheduleConst 0x1BD11BDAA9FC1A22L
+
+/**
+ * Which Threefish size to use
+ */
+enum threefish_size {
+ Threefish256 = 256, /*!< Skein with 256 bit state */
+ Threefish512 = 512, /*!< Skein with 512 bit state */
+ Threefish1024 = 1024 /*!< Skein with 1024 bit state */
+};
+
+/**
+ * Context for Threefish key and tweak words.
+ *
+ * This structure was setup with some know-how of the internal
+ * Skein structures, in particular ordering of header and size dependent
+ * variables. If Skein implementation changes this, the adapt these
+ * structures as well.
+ */
+struct threefish_key {
+ u64 stateSize;
+ u64 key[SKEIN_MAX_STATE_WORDS+1]; /* max number of key words*/
+ u64 tweak[3];
+};
+
+/**
+ * Set Threefish key and tweak data.
+ *
+ * This function sets the key and tweak data for the Threefish cipher of
+ * the given size. The key data must have the same length (number of bits)
+ * as the state size
+ *
+ * @param keyCtx
+ * Pointer to a Threefish key structure.
+ * @param size
+ * Which Skein size to use.
+ * @param keyData
+ * Pointer to the key words (word has 64 bits).
+ * @param tweak
+ * Pointer to the two tweak words (word has 64 bits).
+ */
+void threefishSetKey(struct threefish_key *keyCtx,
+ enum threefish_size stateSize,
+ u64 *keyData, u64 *tweak);
+
+/**
+ * Encrypt Threefisch block (bytes).
+ *
+ * The buffer must have at least the same length (number of bits) aas the
+ * state size for this key. The function uses the first @c stateSize bits
+ * of the input buffer, encrypts them and stores the result in the output
+ * buffer.
+ *
+ * @param keyCtx
+ * Pointer to a Threefish key structure.
+ * @param in
+ * Poionter to plaintext data buffer.
+ * @param out
+ * Pointer to cipher buffer.
+ */
+void threefishEncryptBlockBytes(struct threefish_key *keyCtx, u8 *in, u8 *out);
+
+/**
+ * Encrypt Threefisch block (words).
+ *
+ * The buffer must have at least the same length (number of bits) aas the
+ * state size for this key. The function uses the first @c stateSize bits
+ * of the input buffer, encrypts them and stores the result in the output
+ * buffer.
+ *
+ * The wordsize ist set to 64 bits.
+ *
+ * @param keyCtx
+ * Pointer to a Threefish key structure.
+ * @param in
+ * Poionter to plaintext data buffer.
+ * @param out
+ * Pointer to cipher buffer.
+ */
+void threefishEncryptBlockWords(struct threefish_key *keyCtx, u64 *in,
+ u64 *out);
+
+/**
+ * Decrypt Threefisch block (bytes).
+ *
+ * The buffer must have at least the same length (number of bits) aas the
+ * state size for this key. The function uses the first @c stateSize bits
+ * of the input buffer, decrypts them and stores the result in the output
+ * buffer
+ *
+ * @param keyCtx
+ * Pointer to a Threefish key structure.
+ * @param in
+ * Poionter to cipher data buffer.
+ * @param out
+ * Pointer to plaintext buffer.
+ */
+void threefishDecryptBlockBytes(struct threefish_key *keyCtx, u8 *in, u8 *out);
+
+/**
+ * Decrypt Threefisch block (words).
+ *
+ * The buffer must have at least the same length (number of bits) aas the
+ * state size for this key. The function uses the first @c stateSize bits
+ * of the input buffer, encrypts them and stores the result in the output
+ * buffer.
+ *
+ * The wordsize ist set to 64 bits.
+ *
+ * @param keyCtx
+ * Pointer to a Threefish key structure.
+ * @param in
+ * Poionter to cipher data buffer.
+ * @param out
+ * Pointer to plaintext buffer.
+ */
+void threefishDecryptBlockWords(struct threefish_key *keyCtx, u64 *in,
+ u64 *out);
+
+void threefishEncrypt256(struct threefish_key *keyCtx, u64 *input, u64 *output);
+void threefishEncrypt512(struct threefish_key *keyCtx, u64 *input, u64 *output);
+void threefishEncrypt1024(struct threefish_key *keyCtx, u64 *input,
+ u64 *output);
+void threefishDecrypt256(struct threefish_key *keyCtx, u64 *input, u64 *output);
+void threefishDecrypt512(struct threefish_key *keyCtx, u64 *input, u64 *output);
+void threefishDecrypt1024(struct threefish_key *keyCtx, u64 *input,
+ u64 *output);
+/**
+ * @}
+ */
+#endif
--- /dev/null
+/***********************************************************************
+**
+** Implementation of the Skein hash function.
+**
+** Source code author: Doug Whiting, 2008.
+**
+** This algorithm and source code is released to the public domain.
+**
+************************************************************************/
+
+#define SKEIN_PORT_CODE /* instantiate any code in skein_port.h */
+
+#include <linux/string.h> /* get the memcpy/memset functions */
+#include <skein.h> /* get the Skein API definitions */
+#include <skein_iv.h> /* get precomputed IVs */
+#include <skein_block.h>
+
+/*****************************************************************/
+/* 256-bit Skein */
+/*****************************************************************/
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* init the context for a straight hashing operation */
+int Skein_256_Init(struct skein_256_ctx *ctx, size_t hashBitLen)
+{
+ union {
+ u8 b[SKEIN_256_STATE_BYTES];
+ u64 w[SKEIN_256_STATE_WORDS];
+ } cfg; /* config block */
+
+ Skein_Assert(hashBitLen > 0, SKEIN_BAD_HASHLEN);
+ ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
+
+ switch (hashBitLen) { /* use pre-computed values, where available */
+ case 256:
+ memcpy(ctx->X, SKEIN_256_IV_256, sizeof(ctx->X));
+ break;
+ case 224:
+ memcpy(ctx->X, SKEIN_256_IV_224, sizeof(ctx->X));
+ break;
+ case 160:
+ memcpy(ctx->X, SKEIN_256_IV_160, sizeof(ctx->X));
+ break;
+ case 128:
+ memcpy(ctx->X, SKEIN_256_IV_128, sizeof(ctx->X));
+ break;
+ default:
+ /* here if there is no precomputed IV value available */
+ /*
+ * build/process the config block, type == CONFIG (could be
+ * precomputed)
+ */
+ /* set tweaks: T0=0; T1=CFG | FINAL */
+ Skein_Start_New_Type(ctx, CFG_FINAL);
+
+ /* set the schema, version */
+ cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
+ /* hash result length in bits */
+ cfg.w[1] = Skein_Swap64(hashBitLen);
+ cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
+ /* zero pad config block */
+ memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
+
+ /* compute the initial chaining values from config block */
+ /* zero the chaining variables */
+ memset(ctx->X, 0, sizeof(ctx->X));
+ Skein_256_Process_Block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
+ break;
+ }
+ /* The chaining vars ctx->X are now initialized for hashBitLen. */
+ /* Set up to process the data message portion of the hash (default) */
+ Skein_Start_New_Type(ctx, MSG); /* T0=0, T1= MSG type */
+
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* init the context for a MAC and/or tree hash operation */
+/* [identical to Skein_256_Init() when keyBytes == 0 && \
+ * treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
+int Skein_256_InitExt(struct skein_256_ctx *ctx, size_t hashBitLen,
+ u64 treeInfo, const u8 *key, size_t keyBytes)
+{
+ union {
+ u8 b[SKEIN_256_STATE_BYTES];
+ u64 w[SKEIN_256_STATE_WORDS];
+ } cfg; /* config block */
+
+ Skein_Assert(hashBitLen > 0, SKEIN_BAD_HASHLEN);
+ Skein_Assert(keyBytes == 0 || key != NULL, SKEIN_FAIL);
+
+ /* compute the initial chaining values ctx->X[], based on key */
+ if (keyBytes == 0) { /* is there a key? */
+ /* no key: use all zeroes as key for config block */
+ memset(ctx->X, 0, sizeof(ctx->X));
+ } else { /* here to pre-process a key */
+ Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));
+ /* do a mini-Init right here */
+ /* set output hash bit count = state size */
+ ctx->h.hashBitLen = 8*sizeof(ctx->X);
+ /* set tweaks: T0 = 0; T1 = KEY type */
+ Skein_Start_New_Type(ctx, KEY);
+ /* zero the initial chaining variables */
+ memset(ctx->X, 0, sizeof(ctx->X));
+ /* hash the key */
+ Skein_256_Update(ctx, key, keyBytes);
+ /* put result into cfg.b[] */
+ Skein_256_Final_Pad(ctx, cfg.b);
+ /* copy over into ctx->X[] */
+ memcpy(ctx->X, cfg.b, sizeof(cfg.b));
+ }
+ /*
+ * build/process the config block, type == CONFIG (could be
+ * precomputed for each key)
+ */
+ /* output hash bit count */
+ ctx->h.hashBitLen = hashBitLen;
+ Skein_Start_New_Type(ctx, CFG_FINAL);
+
+ /* pre-pad cfg.w[] with zeroes */
+ memset(&cfg.w, 0, sizeof(cfg.w));
+ cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
+ /* hash result length in bits */
+ cfg.w[1] = Skein_Swap64(hashBitLen);
+ /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
+ cfg.w[2] = Skein_Swap64(treeInfo);
+
+ Skein_Show_Key(256, &ctx->h, key, keyBytes);
+
+ /* compute the initial chaining values from config block */
+ Skein_256_Process_Block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
+
+ /* The chaining vars ctx->X are now initialized */
+ /* Set up to process the data message portion of the hash (default) */
+ Skein_Start_New_Type(ctx, MSG);
+
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* process the input bytes */
+int Skein_256_Update(struct skein_256_ctx *ctx, const u8 *msg,
+ size_t msgByteCnt)
+{
+ size_t n;
+
+ /* catch uninitialized context */
+ Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
+
+ /* process full blocks, if any */
+ if (msgByteCnt + ctx->h.bCnt > SKEIN_256_BLOCK_BYTES) {
+ /* finish up any buffered message data */
+ if (ctx->h.bCnt) {
+ /* # bytes free in buffer b[] */
+ n = SKEIN_256_BLOCK_BYTES - ctx->h.bCnt;
+ if (n) {
+ /* check on our logic here */
+ Skein_assert(n < msgByteCnt);
+ memcpy(&ctx->b[ctx->h.bCnt], msg, n);
+ msgByteCnt -= n;
+ msg += n;
+ ctx->h.bCnt += n;
+ }
+ Skein_assert(ctx->h.bCnt == SKEIN_256_BLOCK_BYTES);
+ Skein_256_Process_Block(ctx, ctx->b, 1,
+ SKEIN_256_BLOCK_BYTES);
+ ctx->h.bCnt = 0;
+ }
+ /*
+ * now process any remaining full blocks, directly from input
+ * message data
+ */
+ if (msgByteCnt > SKEIN_256_BLOCK_BYTES) {
+ /* number of full blocks to process */
+ n = (msgByteCnt-1) / SKEIN_256_BLOCK_BYTES;
+ Skein_256_Process_Block(ctx, msg, n,
+ SKEIN_256_BLOCK_BYTES);
+ msgByteCnt -= n * SKEIN_256_BLOCK_BYTES;
+ msg += n * SKEIN_256_BLOCK_BYTES;
+ }
+ Skein_assert(ctx->h.bCnt == 0);
+ }
+
+ /* copy any remaining source message data bytes into b[] */
+ if (msgByteCnt) {
+ Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES);
+ memcpy(&ctx->b[ctx->h.bCnt], msg, msgByteCnt);
+ ctx->h.bCnt += msgByteCnt;
+ }
+
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* finalize the hash computation and output the result */
+int Skein_256_Final(struct skein_256_ctx *ctx, u8 *hashVal)
+{
+ size_t i, n, byteCnt;
+ u64 X[SKEIN_256_STATE_WORDS];
+ /* catch uninitialized context */
+ Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
+
+ /* tag as the final block */
+ ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;
+ /* zero pad b[] if necessary */
+ if (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES)
+ memset(&ctx->b[ctx->h.bCnt], 0,
+ SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);
+
+ /* process the final block */
+ Skein_256_Process_Block(ctx, ctx->b, 1, ctx->h.bCnt);
+
+ /* now output the result */
+ /* total number of output bytes */
+ byteCnt = (ctx->h.hashBitLen + 7) >> 3;
+
+ /* run Threefish in "counter mode" to generate output */
+ /* zero out b[], so it can hold the counter */
+ memset(ctx->b, 0, sizeof(ctx->b));
+ /* keep a local copy of counter mode "key" */
+ memcpy(X, ctx->X, sizeof(X));
+ for (i = 0; i*SKEIN_256_BLOCK_BYTES < byteCnt; i++) {
+ /* build the counter block */
+ ((u64 *)ctx->b)[0] = Skein_Swap64((u64) i);
+ Skein_Start_New_Type(ctx, OUT_FINAL);
+ /* run "counter mode" */
+ Skein_256_Process_Block(ctx, ctx->b, 1, sizeof(u64));
+ /* number of output bytes left to go */
+ n = byteCnt - i*SKEIN_256_BLOCK_BYTES;
+ if (n >= SKEIN_256_BLOCK_BYTES)
+ n = SKEIN_256_BLOCK_BYTES;
+ /* "output" the ctr mode bytes */
+ Skein_Put64_LSB_First(hashVal+i*SKEIN_256_BLOCK_BYTES, ctx->X,
+ n);
+ Skein_Show_Final(256, &ctx->h, n,
+ hashVal+i*SKEIN_256_BLOCK_BYTES);
+ /* restore the counter mode key for next time */
+ memcpy(ctx->X, X, sizeof(X));
+ }
+ return SKEIN_SUCCESS;
+}
+
+/*****************************************************************/
+/* 512-bit Skein */
+/*****************************************************************/
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* init the context for a straight hashing operation */
+int Skein_512_Init(struct skein_512_ctx *ctx, size_t hashBitLen)
+{
+ union {
+ u8 b[SKEIN_512_STATE_BYTES];
+ u64 w[SKEIN_512_STATE_WORDS];
+ } cfg; /* config block */
+
+ Skein_Assert(hashBitLen > 0, SKEIN_BAD_HASHLEN);
+ ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
+
+ switch (hashBitLen) { /* use pre-computed values, where available */
+ case 512:
+ memcpy(ctx->X, SKEIN_512_IV_512, sizeof(ctx->X));
+ break;
+ case 384:
+ memcpy(ctx->X, SKEIN_512_IV_384, sizeof(ctx->X));
+ break;
+ case 256:
+ memcpy(ctx->X, SKEIN_512_IV_256, sizeof(ctx->X));
+ break;
+ case 224:
+ memcpy(ctx->X, SKEIN_512_IV_224, sizeof(ctx->X));
+ break;
+ default:
+ /* here if there is no precomputed IV value available */
+ /*
+ * build/process the config block, type == CONFIG (could be
+ * precomputed)
+ */
+ /* set tweaks: T0=0; T1=CFG | FINAL */
+ Skein_Start_New_Type(ctx, CFG_FINAL);
+
+ /* set the schema, version */
+ cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
+ /* hash result length in bits */
+ cfg.w[1] = Skein_Swap64(hashBitLen);
+ cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
+ /* zero pad config block */
+ memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
+
+ /* compute the initial chaining values from config block */
+ /* zero the chaining variables */
+ memset(ctx->X, 0, sizeof(ctx->X));
+ Skein_512_Process_Block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
+ break;
+ }
+
+ /*
+ * The chaining vars ctx->X are now initialized for the given
+ * hashBitLen.
+ */
+ /* Set up to process the data message portion of the hash (default) */
+ Skein_Start_New_Type(ctx, MSG); /* T0=0, T1= MSG type */
+
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* init the context for a MAC and/or tree hash operation */
+/* [identical to Skein_512_Init() when keyBytes == 0 && \
+ * treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
+int Skein_512_InitExt(struct skein_512_ctx *ctx, size_t hashBitLen,
+ u64 treeInfo, const u8 *key, size_t keyBytes)
+{
+ union {
+ u8 b[SKEIN_512_STATE_BYTES];
+ u64 w[SKEIN_512_STATE_WORDS];
+ } cfg; /* config block */
+
+ Skein_Assert(hashBitLen > 0, SKEIN_BAD_HASHLEN);
+ Skein_Assert(keyBytes == 0 || key != NULL, SKEIN_FAIL);
+
+ /* compute the initial chaining values ctx->X[], based on key */
+ if (keyBytes == 0) { /* is there a key? */
+ /* no key: use all zeroes as key for config block */
+ memset(ctx->X, 0, sizeof(ctx->X));
+ } else { /* here to pre-process a key */
+ Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));
+ /* do a mini-Init right here */
+ /* set output hash bit count = state size */
+ ctx->h.hashBitLen = 8*sizeof(ctx->X);
+ /* set tweaks: T0 = 0; T1 = KEY type */
+ Skein_Start_New_Type(ctx, KEY);
+ /* zero the initial chaining variables */
+ memset(ctx->X, 0, sizeof(ctx->X));
+ /* hash the key */
+ Skein_512_Update(ctx, key, keyBytes);
+ /* put result into cfg.b[] */
+ Skein_512_Final_Pad(ctx, cfg.b);
+ /* copy over into ctx->X[] */
+ memcpy(ctx->X, cfg.b, sizeof(cfg.b));
+ }
+ /*
+ * build/process the config block, type == CONFIG (could be
+ * precomputed for each key)
+ */
+ ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
+ Skein_Start_New_Type(ctx, CFG_FINAL);
+
+ /* pre-pad cfg.w[] with zeroes */
+ memset(&cfg.w, 0, sizeof(cfg.w));
+ cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
+ /* hash result length in bits */
+ cfg.w[1] = Skein_Swap64(hashBitLen);
+ /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
+ cfg.w[2] = Skein_Swap64(treeInfo);
+
+ Skein_Show_Key(512, &ctx->h, key, keyBytes);
+
+ /* compute the initial chaining values from config block */
+ Skein_512_Process_Block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
+
+ /* The chaining vars ctx->X are now initialized */
+ /* Set up to process the data message portion of the hash (default) */
+ Skein_Start_New_Type(ctx, MSG);
+
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* process the input bytes */
+int Skein_512_Update(struct skein_512_ctx *ctx, const u8 *msg,
+ size_t msgByteCnt)
+{
+ size_t n;
+
+ /* catch uninitialized context */
+ Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
+
+ /* process full blocks, if any */
+ if (msgByteCnt + ctx->h.bCnt > SKEIN_512_BLOCK_BYTES) {
+ /* finish up any buffered message data */
+ if (ctx->h.bCnt) {
+ /* # bytes free in buffer b[] */
+ n = SKEIN_512_BLOCK_BYTES - ctx->h.bCnt;
+ if (n) {
+ /* check on our logic here */
+ Skein_assert(n < msgByteCnt);
+ memcpy(&ctx->b[ctx->h.bCnt], msg, n);
+ msgByteCnt -= n;
+ msg += n;
+ ctx->h.bCnt += n;
+ }
+ Skein_assert(ctx->h.bCnt == SKEIN_512_BLOCK_BYTES);
+ Skein_512_Process_Block(ctx, ctx->b, 1,
+ SKEIN_512_BLOCK_BYTES);
+ ctx->h.bCnt = 0;
+ }
+ /*
+ * now process any remaining full blocks, directly from input
+ * message data
+ */
+ if (msgByteCnt > SKEIN_512_BLOCK_BYTES) {
+ /* number of full blocks to process */
+ n = (msgByteCnt-1) / SKEIN_512_BLOCK_BYTES;
+ Skein_512_Process_Block(ctx, msg, n,
+ SKEIN_512_BLOCK_BYTES);
+ msgByteCnt -= n * SKEIN_512_BLOCK_BYTES;
+ msg += n * SKEIN_512_BLOCK_BYTES;
+ }
+ Skein_assert(ctx->h.bCnt == 0);
+ }
+
+ /* copy any remaining source message data bytes into b[] */
+ if (msgByteCnt) {
+ Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES);
+ memcpy(&ctx->b[ctx->h.bCnt], msg, msgByteCnt);
+ ctx->h.bCnt += msgByteCnt;
+ }
+
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* finalize the hash computation and output the result */
+int Skein_512_Final(struct skein_512_ctx *ctx, u8 *hashVal)
+{
+ size_t i, n, byteCnt;
+ u64 X[SKEIN_512_STATE_WORDS];
+ /* catch uninitialized context */
+ Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
+
+ /* tag as the final block */
+ ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;
+ /* zero pad b[] if necessary */
+ if (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES)
+ memset(&ctx->b[ctx->h.bCnt], 0,
+ SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);
+
+ /* process the final block */
+ Skein_512_Process_Block(ctx, ctx->b, 1, ctx->h.bCnt);
+
+ /* now output the result */
+ /* total number of output bytes */
+ byteCnt = (ctx->h.hashBitLen + 7) >> 3;
+
+ /* run Threefish in "counter mode" to generate output */
+ /* zero out b[], so it can hold the counter */
+ memset(ctx->b, 0, sizeof(ctx->b));
+ /* keep a local copy of counter mode "key" */
+ memcpy(X, ctx->X, sizeof(X));
+ for (i = 0; i*SKEIN_512_BLOCK_BYTES < byteCnt; i++) {
+ /* build the counter block */
+ ((u64 *)ctx->b)[0] = Skein_Swap64((u64) i);
+ Skein_Start_New_Type(ctx, OUT_FINAL);
+ /* run "counter mode" */
+ Skein_512_Process_Block(ctx, ctx->b, 1, sizeof(u64));
+ /* number of output bytes left to go */
+ n = byteCnt - i*SKEIN_512_BLOCK_BYTES;
+ if (n >= SKEIN_512_BLOCK_BYTES)
+ n = SKEIN_512_BLOCK_BYTES;
+ /* "output" the ctr mode bytes */
+ Skein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES, ctx->X,
+ n);
+ Skein_Show_Final(512, &ctx->h, n,
+ hashVal+i*SKEIN_512_BLOCK_BYTES);
+ /* restore the counter mode key for next time */
+ memcpy(ctx->X, X, sizeof(X));
+ }
+ return SKEIN_SUCCESS;
+}
+
+/*****************************************************************/
+/* 1024-bit Skein */
+/*****************************************************************/
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* init the context for a straight hashing operation */
+int Skein1024_Init(struct skein1024_ctx *ctx, size_t hashBitLen)
+{
+ union {
+ u8 b[SKEIN1024_STATE_BYTES];
+ u64 w[SKEIN1024_STATE_WORDS];
+ } cfg; /* config block */
+
+ Skein_Assert(hashBitLen > 0, SKEIN_BAD_HASHLEN);
+ ctx->h.hashBitLen = hashBitLen; /* output hash bit count */
+
+ switch (hashBitLen) { /* use pre-computed values, where available */
+ case 512:
+ memcpy(ctx->X, SKEIN1024_IV_512, sizeof(ctx->X));
+ break;
+ case 384:
+ memcpy(ctx->X, SKEIN1024_IV_384, sizeof(ctx->X));
+ break;
+ case 1024:
+ memcpy(ctx->X, SKEIN1024_IV_1024, sizeof(ctx->X));
+ break;
+ default:
+ /* here if there is no precomputed IV value available */
+ /*
+ * build/process the config block, type == CONFIG
+ * (could be precomputed)
+ */
+ /* set tweaks: T0=0; T1=CFG | FINAL */
+ Skein_Start_New_Type(ctx, CFG_FINAL);
+
+ /* set the schema, version */
+ cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
+ /* hash result length in bits */
+ cfg.w[1] = Skein_Swap64(hashBitLen);
+ cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
+ /* zero pad config block */
+ memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
+
+ /* compute the initial chaining values from config block */
+ /* zero the chaining variables */
+ memset(ctx->X, 0, sizeof(ctx->X));
+ Skein1024_Process_Block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
+ break;
+ }
+
+ /* The chaining vars ctx->X are now initialized for the hashBitLen. */
+ /* Set up to process the data message portion of the hash (default) */
+ Skein_Start_New_Type(ctx, MSG); /* T0=0, T1= MSG type */
+
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* init the context for a MAC and/or tree hash operation */
+/* [identical to Skein1024_Init() when keyBytes == 0 && \
+ * treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
+int Skein1024_InitExt(struct skein1024_ctx *ctx, size_t hashBitLen,
+ u64 treeInfo, const u8 *key, size_t keyBytes)
+{
+ union {
+ u8 b[SKEIN1024_STATE_BYTES];
+ u64 w[SKEIN1024_STATE_WORDS];
+ } cfg; /* config block */
+
+ Skein_Assert(hashBitLen > 0, SKEIN_BAD_HASHLEN);
+ Skein_Assert(keyBytes == 0 || key != NULL, SKEIN_FAIL);
+
+ /* compute the initial chaining values ctx->X[], based on key */
+ if (keyBytes == 0) { /* is there a key? */
+ /* no key: use all zeroes as key for config block */
+ memset(ctx->X, 0, sizeof(ctx->X));
+ } else { /* here to pre-process a key */
+ Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));
+ /* do a mini-Init right here */
+ /* set output hash bit count = state size */
+ ctx->h.hashBitLen = 8*sizeof(ctx->X);
+ /* set tweaks: T0 = 0; T1 = KEY type */
+ Skein_Start_New_Type(ctx, KEY);
+ /* zero the initial chaining variables */
+ memset(ctx->X, 0, sizeof(ctx->X));
+ /* hash the key */
+ Skein1024_Update(ctx, key, keyBytes);
+ /* put result into cfg.b[] */
+ Skein1024_Final_Pad(ctx, cfg.b);
+ /* copy over into ctx->X[] */
+ memcpy(ctx->X, cfg.b, sizeof(cfg.b));
+ }
+ /*
+ * build/process the config block, type == CONFIG (could be
+ * precomputed for each key)
+ */
+ /* output hash bit count */
+ ctx->h.hashBitLen = hashBitLen;
+ Skein_Start_New_Type(ctx, CFG_FINAL);
+
+ /* pre-pad cfg.w[] with zeroes */
+ memset(&cfg.w, 0, sizeof(cfg.w));
+ cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);
+ /* hash result length in bits */
+ cfg.w[1] = Skein_Swap64(hashBitLen);
+ /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
+ cfg.w[2] = Skein_Swap64(treeInfo);
+
+ Skein_Show_Key(1024, &ctx->h, key, keyBytes);
+
+ /* compute the initial chaining values from config block */
+ Skein1024_Process_Block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
+
+ /* The chaining vars ctx->X are now initialized */
+ /* Set up to process the data message portion of the hash (default) */
+ Skein_Start_New_Type(ctx, MSG);
+
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* process the input bytes */
+int Skein1024_Update(struct skein1024_ctx *ctx, const u8 *msg,
+ size_t msgByteCnt)
+{
+ size_t n;
+
+ /* catch uninitialized context */
+ Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES, SKEIN_FAIL);
+
+ /* process full blocks, if any */
+ if (msgByteCnt + ctx->h.bCnt > SKEIN1024_BLOCK_BYTES) {
+ /* finish up any buffered message data */
+ if (ctx->h.bCnt) {
+ /* # bytes free in buffer b[] */
+ n = SKEIN1024_BLOCK_BYTES - ctx->h.bCnt;
+ if (n) {
+ /* check on our logic here */
+ Skein_assert(n < msgByteCnt);
+ memcpy(&ctx->b[ctx->h.bCnt], msg, n);
+ msgByteCnt -= n;
+ msg += n;
+ ctx->h.bCnt += n;
+ }
+ Skein_assert(ctx->h.bCnt == SKEIN1024_BLOCK_BYTES);
+ Skein1024_Process_Block(ctx, ctx->b, 1,
+ SKEIN1024_BLOCK_BYTES);
+ ctx->h.bCnt = 0;
+ }
+ /*
+ * now process any remaining full blocks, directly from input
+ * message data
+ */
+ if (msgByteCnt > SKEIN1024_BLOCK_BYTES) {
+ /* number of full blocks to process */
+ n = (msgByteCnt-1) / SKEIN1024_BLOCK_BYTES;
+ Skein1024_Process_Block(ctx, msg, n,
+ SKEIN1024_BLOCK_BYTES);
+ msgByteCnt -= n * SKEIN1024_BLOCK_BYTES;
+ msg += n * SKEIN1024_BLOCK_BYTES;
+ }
+ Skein_assert(ctx->h.bCnt == 0);
+ }
+
+ /* copy any remaining source message data bytes into b[] */
+ if (msgByteCnt) {
+ Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES);
+ memcpy(&ctx->b[ctx->h.bCnt], msg, msgByteCnt);
+ ctx->h.bCnt += msgByteCnt;
+ }
+
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* finalize the hash computation and output the result */
+int Skein1024_Final(struct skein1024_ctx *ctx, u8 *hashVal)
+{
+ size_t i, n, byteCnt;
+ u64 X[SKEIN1024_STATE_WORDS];
+ /* catch uninitialized context */
+ Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES, SKEIN_FAIL);
+
+ /* tag as the final block */
+ ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;
+ /* zero pad b[] if necessary */
+ if (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)
+ memset(&ctx->b[ctx->h.bCnt], 0,
+ SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);
+
+ /* process the final block */
+ Skein1024_Process_Block(ctx, ctx->b, 1, ctx->h.bCnt);
+
+ /* now output the result */
+ /* total number of output bytes */
+ byteCnt = (ctx->h.hashBitLen + 7) >> 3;
+
+ /* run Threefish in "counter mode" to generate output */
+ /* zero out b[], so it can hold the counter */
+ memset(ctx->b, 0, sizeof(ctx->b));
+ /* keep a local copy of counter mode "key" */
+ memcpy(X, ctx->X, sizeof(X));
+ for (i = 0; i*SKEIN1024_BLOCK_BYTES < byteCnt; i++) {
+ /* build the counter block */
+ ((u64 *)ctx->b)[0] = Skein_Swap64((u64) i);
+ Skein_Start_New_Type(ctx, OUT_FINAL);
+ /* run "counter mode" */
+ Skein1024_Process_Block(ctx, ctx->b, 1, sizeof(u64));
+ /* number of output bytes left to go */
+ n = byteCnt - i*SKEIN1024_BLOCK_BYTES;
+ if (n >= SKEIN1024_BLOCK_BYTES)
+ n = SKEIN1024_BLOCK_BYTES;
+ /* "output" the ctr mode bytes */
+ Skein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES, ctx->X,
+ n);
+ Skein_Show_Final(1024, &ctx->h, n,
+ hashVal+i*SKEIN1024_BLOCK_BYTES);
+ /* restore the counter mode key for next time */
+ memcpy(ctx->X, X, sizeof(X));
+ }
+ return SKEIN_SUCCESS;
+}
+
+/**************** Functions to support MAC/tree hashing ***************/
+/* (this code is identical for Optimized and Reference versions) */
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* finalize the hash computation and output the block, no OUTPUT stage */
+int Skein_256_Final_Pad(struct skein_256_ctx *ctx, u8 *hashVal)
+{
+ /* catch uninitialized context */
+ Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
+
+ /* tag as the final block */
+ ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;
+ /* zero pad b[] if necessary */
+ if (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES)
+ memset(&ctx->b[ctx->h.bCnt], 0,
+ SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);
+ /* process the final block */
+ Skein_256_Process_Block(ctx, ctx->b, 1, ctx->h.bCnt);
+
+ /* "output" the state bytes */
+ Skein_Put64_LSB_First(hashVal, ctx->X, SKEIN_256_BLOCK_BYTES);
+
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* finalize the hash computation and output the block, no OUTPUT stage */
+int Skein_512_Final_Pad(struct skein_512_ctx *ctx, u8 *hashVal)
+{
+ /* catch uninitialized context */
+ Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
+
+ /* tag as the final block */
+ ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;
+ /* zero pad b[] if necessary */
+ if (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES)
+ memset(&ctx->b[ctx->h.bCnt], 0,
+ SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);
+ /* process the final block */
+ Skein_512_Process_Block(ctx, ctx->b, 1, ctx->h.bCnt);
+
+ /* "output" the state bytes */
+ Skein_Put64_LSB_First(hashVal, ctx->X, SKEIN_512_BLOCK_BYTES);
+
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* finalize the hash computation and output the block, no OUTPUT stage */
+int Skein1024_Final_Pad(struct skein1024_ctx *ctx, u8 *hashVal)
+{
+ /* catch uninitialized context */
+ Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES, SKEIN_FAIL);
+
+ /* tag as the final block */
+ ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;
+ /* zero pad b[] if necessary */
+ if (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)
+ memset(&ctx->b[ctx->h.bCnt], 0,
+ SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);
+ /* process the final block */
+ Skein1024_Process_Block(ctx, ctx->b, 1, ctx->h.bCnt);
+
+ /* "output" the state bytes */
+ Skein_Put64_LSB_First(hashVal, ctx->X, SKEIN1024_BLOCK_BYTES);
+
+ return SKEIN_SUCCESS;
+}
+
+#if SKEIN_TREE_HASH
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* just do the OUTPUT stage */
+int Skein_256_Output(struct skein_256_ctx *ctx, u8 *hashVal)
+{
+ size_t i, n, byteCnt;
+ u64 X[SKEIN_256_STATE_WORDS];
+ /* catch uninitialized context */
+ Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
+
+ /* now output the result */
+ /* total number of output bytes */
+ byteCnt = (ctx->h.hashBitLen + 7) >> 3;
+
+ /* run Threefish in "counter mode" to generate output */
+ /* zero out b[], so it can hold the counter */
+ memset(ctx->b, 0, sizeof(ctx->b));
+ /* keep a local copy of counter mode "key" */
+ memcpy(X, ctx->X, sizeof(X));
+ for (i = 0; i*SKEIN_256_BLOCK_BYTES < byteCnt; i++) {
+ /* build the counter block */
+ ((u64 *)ctx->b)[0] = Skein_Swap64((u64) i);
+ Skein_Start_New_Type(ctx, OUT_FINAL);
+ /* run "counter mode" */
+ Skein_256_Process_Block(ctx, ctx->b, 1, sizeof(u64));
+ /* number of output bytes left to go */
+ n = byteCnt - i*SKEIN_256_BLOCK_BYTES;
+ if (n >= SKEIN_256_BLOCK_BYTES)
+ n = SKEIN_256_BLOCK_BYTES;
+ /* "output" the ctr mode bytes */
+ Skein_Put64_LSB_First(hashVal+i*SKEIN_256_BLOCK_BYTES, ctx->X,
+ n);
+ Skein_Show_Final(256, &ctx->h, n,
+ hashVal+i*SKEIN_256_BLOCK_BYTES);
+ /* restore the counter mode key for next time */
+ memcpy(ctx->X, X, sizeof(X));
+ }
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* just do the OUTPUT stage */
+int Skein_512_Output(struct skein_512_ctx *ctx, u8 *hashVal)
+{
+ size_t i, n, byteCnt;
+ u64 X[SKEIN_512_STATE_WORDS];
+ /* catch uninitialized context */
+ Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
+
+ /* now output the result */
+ /* total number of output bytes */
+ byteCnt = (ctx->h.hashBitLen + 7) >> 3;
+
+ /* run Threefish in "counter mode" to generate output */
+ /* zero out b[], so it can hold the counter */
+ memset(ctx->b, 0, sizeof(ctx->b));
+ /* keep a local copy of counter mode "key" */
+ memcpy(X, ctx->X, sizeof(X));
+ for (i = 0; i*SKEIN_512_BLOCK_BYTES < byteCnt; i++) {
+ /* build the counter block */
+ ((u64 *)ctx->b)[0] = Skein_Swap64((u64) i);
+ Skein_Start_New_Type(ctx, OUT_FINAL);
+ /* run "counter mode" */
+ Skein_512_Process_Block(ctx, ctx->b, 1, sizeof(u64));
+ /* number of output bytes left to go */
+ n = byteCnt - i*SKEIN_512_BLOCK_BYTES;
+ if (n >= SKEIN_512_BLOCK_BYTES)
+ n = SKEIN_512_BLOCK_BYTES;
+ /* "output" the ctr mode bytes */
+ Skein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES, ctx->X,
+ n);
+ Skein_Show_Final(256, &ctx->h, n,
+ hashVal+i*SKEIN_512_BLOCK_BYTES);
+ /* restore the counter mode key for next time */
+ memcpy(ctx->X, X, sizeof(X));
+ }
+ return SKEIN_SUCCESS;
+}
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/* just do the OUTPUT stage */
+int Skein1024_Output(struct skein1024_ctx *ctx, u8 *hashVal)
+{
+ size_t i, n, byteCnt;
+ u64 X[SKEIN1024_STATE_WORDS];
+ /* catch uninitialized context */
+ Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES, SKEIN_FAIL);
+
+ /* now output the result */
+ /* total number of output bytes */
+ byteCnt = (ctx->h.hashBitLen + 7) >> 3;
+
+ /* run Threefish in "counter mode" to generate output */
+ /* zero out b[], so it can hold the counter */
+ memset(ctx->b, 0, sizeof(ctx->b));
+ /* keep a local copy of counter mode "key" */
+ memcpy(X, ctx->X, sizeof(X));
+ for (i = 0; i*SKEIN1024_BLOCK_BYTES < byteCnt; i++) {
+ /* build the counter block */
+ ((u64 *)ctx->b)[0] = Skein_Swap64((u64) i);
+ Skein_Start_New_Type(ctx, OUT_FINAL);
+ /* run "counter mode" */
+ Skein1024_Process_Block(ctx, ctx->b, 1, sizeof(u64));
+ /* number of output bytes left to go */
+ n = byteCnt - i*SKEIN1024_BLOCK_BYTES;
+ if (n >= SKEIN1024_BLOCK_BYTES)
+ n = SKEIN1024_BLOCK_BYTES;
+ /* "output" the ctr mode bytes */
+ Skein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES, ctx->X,
+ n);
+ Skein_Show_Final(256, &ctx->h, n,
+ hashVal+i*SKEIN1024_BLOCK_BYTES);
+ /* restore the counter mode key for next time */
+ memcpy(ctx->X, X, sizeof(X));
+ }
+ return SKEIN_SUCCESS;
+}
+#endif
--- /dev/null
+/*
+Copyright (c) 2010 Werner Dittmann
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <linux/string.h>
+#include <skeinApi.h>
+
+int skeinCtxPrepare(struct skein_ctx *ctx, enum skein_size size)
+{
+ Skein_Assert(ctx && size, SKEIN_FAIL);
+
+ memset(ctx , 0, sizeof(struct skein_ctx));
+ ctx->skeinSize = size;
+
+ return SKEIN_SUCCESS;
+}
+
+int skeinInit(struct skein_ctx *ctx, size_t hashBitLen)
+{
+ int ret = SKEIN_FAIL;
+ size_t Xlen = 0;
+ u64 *X = NULL;
+ u64 treeInfo = SKEIN_CFG_TREE_INFO_SEQUENTIAL;
+
+ Skein_Assert(ctx, SKEIN_FAIL);
+ /*
+ * The following two lines rely of the fact that the real Skein
+ * contexts are a union in out context and thus have tha maximum
+ * memory available. The beauty of C :-) .
+ */
+ X = ctx->m.s256.X;
+ Xlen = ctx->skeinSize/8;
+ /*
+ * If size is the same and hash bit length is zero then reuse
+ * the save chaining variables.
+ */
+ switch (ctx->skeinSize) {
+ case Skein256:
+ ret = Skein_256_InitExt(&ctx->m.s256, hashBitLen,
+ treeInfo, NULL, 0);
+ break;
+ case Skein512:
+ ret = Skein_512_InitExt(&ctx->m.s512, hashBitLen,
+ treeInfo, NULL, 0);
+ break;
+ case Skein1024:
+ ret = Skein1024_InitExt(&ctx->m.s1024, hashBitLen,
+ treeInfo, NULL, 0);
+ break;
+ }
+
+ if (ret == SKEIN_SUCCESS) {
+ /*
+ * Save chaining variables for this combination of size and
+ * hashBitLen
+ */
+ memcpy(ctx->XSave, X, Xlen);
+ }
+ return ret;
+}
+
+int skeinMacInit(struct skein_ctx *ctx, const u8 *key, size_t keyLen,
+ size_t hashBitLen)
+{
+ int ret = SKEIN_FAIL;
+ u64 *X = NULL;
+ size_t Xlen = 0;
+ u64 treeInfo = SKEIN_CFG_TREE_INFO_SEQUENTIAL;
+
+ Skein_Assert(ctx, SKEIN_FAIL);
+
+ X = ctx->m.s256.X;
+ Xlen = ctx->skeinSize/8;
+
+ Skein_Assert(hashBitLen, SKEIN_BAD_HASHLEN);
+
+ switch (ctx->skeinSize) {
+ case Skein256:
+ ret = Skein_256_InitExt(&ctx->m.s256, hashBitLen,
+ treeInfo,
+ (const u8 *)key, keyLen);
+
+ break;
+ case Skein512:
+ ret = Skein_512_InitExt(&ctx->m.s512, hashBitLen,
+ treeInfo,
+ (const u8 *)key, keyLen);
+ break;
+ case Skein1024:
+ ret = Skein1024_InitExt(&ctx->m.s1024, hashBitLen,
+ treeInfo,
+ (const u8 *)key, keyLen);
+
+ break;
+ }
+ if (ret == SKEIN_SUCCESS) {
+ /*
+ * Save chaining variables for this combination of key,
+ * keyLen, hashBitLen
+ */
+ memcpy(ctx->XSave, X, Xlen);
+ }
+ return ret;
+}
+
+void skeinReset(struct skein_ctx *ctx)
+{
+ size_t Xlen = 0;
+ u64 *X = NULL;
+
+ /*
+ * The following two lines rely of the fact that the real Skein
+ * contexts are a union in out context and thus have tha maximum
+ * memory available. The beautiy of C :-) .
+ */
+ X = ctx->m.s256.X;
+ Xlen = ctx->skeinSize/8;
+ /* Restore the chaing variable, reset byte counter */
+ memcpy(X, ctx->XSave, Xlen);
+
+ /* Setup context to process the message */
+ Skein_Start_New_Type(&ctx->m, MSG);
+}
+
+int skeinUpdate(struct skein_ctx *ctx, const u8 *msg,
+ size_t msgByteCnt)
+{
+ int ret = SKEIN_FAIL;
+ Skein_Assert(ctx, SKEIN_FAIL);
+
+ switch (ctx->skeinSize) {
+ case Skein256:
+ ret = Skein_256_Update(&ctx->m.s256, (const u8 *)msg,
+ msgByteCnt);
+ break;
+ case Skein512:
+ ret = Skein_512_Update(&ctx->m.s512, (const u8 *)msg,
+ msgByteCnt);
+ break;
+ case Skein1024:
+ ret = Skein1024_Update(&ctx->m.s1024, (const u8 *)msg,
+ msgByteCnt);
+ break;
+ }
+ return ret;
+
+}
+
+int skeinUpdateBits(struct skein_ctx *ctx, const u8 *msg,
+ size_t msgBitCnt)
+{
+ /*
+ * I've used the bit pad implementation from skein_test.c (see NIST CD)
+ * and modified it to use the convenience functions and added some
+ * pointer arithmetic.
+ */
+ size_t length;
+ u8 mask;
+ u8 *up;
+
+ /*
+ * only the final Update() call is allowed do partial bytes, else
+ * assert an error
+ */
+ Skein_Assert((ctx->m.h.T[1] & SKEIN_T1_FLAG_BIT_PAD) == 0 ||
+ msgBitCnt == 0, SKEIN_FAIL);
+
+ /* if number of bits is a multiple of bytes - that's easy */
+ if ((msgBitCnt & 0x7) == 0)
+ return skeinUpdate(ctx, msg, msgBitCnt >> 3);
+
+ skeinUpdate(ctx, msg, (msgBitCnt >> 3) + 1);
+
+ /*
+ * The next line rely on the fact that the real Skein contexts
+ * are a union in our context. After the addition the pointer points to
+ * Skein's real partial block buffer.
+ * If this layout ever changes we have to adapt this as well.
+ */
+ up = (u8 *)ctx->m.s256.X + ctx->skeinSize / 8;
+
+ /* set tweak flag for the skeinFinal call */
+ Skein_Set_Bit_Pad_Flag(ctx->m.h);
+
+ /* now "pad" the final partial byte the way NIST likes */
+ /* get the bCnt value (same location for all block sizes) */
+ length = ctx->m.h.bCnt;
+ /* internal sanity check: there IS a partial byte in the buffer! */
+ Skein_assert(length != 0);
+ /* partial byte bit mask */
+ mask = (u8) (1u << (7 - (msgBitCnt & 7)));
+ /* apply bit padding on final byte (in the buffer) */
+ up[length-1] = (u8)((up[length-1] & (0-mask))|mask);
+
+ return SKEIN_SUCCESS;
+}
+
+int skeinFinal(struct skein_ctx *ctx, u8 *hash)
+{
+ int ret = SKEIN_FAIL;
+ Skein_Assert(ctx, SKEIN_FAIL);
+
+ switch (ctx->skeinSize) {
+ case Skein256:
+ ret = Skein_256_Final(&ctx->m.s256, (u8 *)hash);
+ break;
+ case Skein512:
+ ret = Skein_512_Final(&ctx->m.s512, (u8 *)hash);
+ break;
+ case Skein1024:
+ ret = Skein1024_Final(&ctx->m.s1024, (u8 *)hash);
+ break;
+ }
+ return ret;
+}
--- /dev/null
+
+#include <linux/string.h>
+#include <skein.h>
+#include <threefishApi.h>
+
+
+/***************************** Skein_256 ******************************/
+void Skein_256_Process_Block(struct skein_256_ctx *ctx, const u8 *blkPtr,
+ size_t blkCnt, size_t byteCntAdd)
+{
+ struct threefish_key key;
+ u64 tweak[2];
+ int i;
+ u64 w[SKEIN_256_STATE_WORDS]; /* local copy of input block */
+ u64 words[3];
+
+ Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */
+ tweak[0] = ctx->h.T[0];
+ tweak[1] = ctx->h.T[1];
+
+ do {
+ u64 carry = byteCntAdd;
+
+ words[0] = tweak[0] & 0xffffffffL;
+ words[1] = ((tweak[0] >> 32) & 0xffffffffL);
+ words[2] = (tweak[1] & 0xffffffffL);
+
+ for (i = 0; i < 3; i++) {
+ carry += words[i];
+ words[i] = carry;
+ carry >>= 32;
+ }
+ tweak[0] = words[0] & 0xffffffffL;
+ tweak[0] |= (words[1] & 0xffffffffL) << 32;
+ tweak[1] |= words[2] & 0xffffffffL;
+
+ threefishSetKey(&key, Threefish256, ctx->X, tweak);
+
+ /* get input block in little-endian format */
+ Skein_Get64_LSB_First(w, blkPtr, SKEIN_256_STATE_WORDS);
+
+ threefishEncryptBlockWords(&key, w, ctx->X);
+
+ blkPtr += SKEIN_256_BLOCK_BYTES;
+
+ /* do the final "feedforward" xor, update ctx chaining vars */
+ ctx->X[0] = ctx->X[0] ^ w[0];
+ ctx->X[1] = ctx->X[1] ^ w[1];
+ ctx->X[2] = ctx->X[2] ^ w[2];
+ ctx->X[3] = ctx->X[3] ^ w[3];
+
+ tweak[1] &= ~SKEIN_T1_FLAG_FIRST;
+ } while (--blkCnt);
+
+ ctx->h.T[0] = tweak[0];
+ ctx->h.T[1] = tweak[1];
+}
+
+void Skein_512_Process_Block(struct skein_512_ctx *ctx, const u8 *blkPtr,
+ size_t blkCnt, size_t byteCntAdd)
+{
+ struct threefish_key key;
+ u64 tweak[2];
+ int i;
+ u64 words[3];
+ u64 w[SKEIN_512_STATE_WORDS]; /* local copy of input block */
+
+ Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */
+ tweak[0] = ctx->h.T[0];
+ tweak[1] = ctx->h.T[1];
+
+ do {
+ u64 carry = byteCntAdd;
+
+ words[0] = tweak[0] & 0xffffffffL;
+ words[1] = ((tweak[0] >> 32) & 0xffffffffL);
+ words[2] = (tweak[1] & 0xffffffffL);
+
+ for (i = 0; i < 3; i++) {
+ carry += words[i];
+ words[i] = carry;
+ carry >>= 32;
+ }
+ tweak[0] = words[0] & 0xffffffffL;
+ tweak[0] |= (words[1] & 0xffffffffL) << 32;
+ tweak[1] |= words[2] & 0xffffffffL;
+
+ threefishSetKey(&key, Threefish512, ctx->X, tweak);
+
+ /* get input block in little-endian format */
+ Skein_Get64_LSB_First(w, blkPtr, SKEIN_512_STATE_WORDS);
+
+ threefishEncryptBlockWords(&key, w, ctx->X);
+
+ blkPtr += SKEIN_512_BLOCK_BYTES;
+
+ /* do the final "feedforward" xor, update ctx chaining vars */
+ ctx->X[0] = ctx->X[0] ^ w[0];
+ ctx->X[1] = ctx->X[1] ^ w[1];
+ ctx->X[2] = ctx->X[2] ^ w[2];
+ ctx->X[3] = ctx->X[3] ^ w[3];
+ ctx->X[4] = ctx->X[4] ^ w[4];
+ ctx->X[5] = ctx->X[5] ^ w[5];
+ ctx->X[6] = ctx->X[6] ^ w[6];
+ ctx->X[7] = ctx->X[7] ^ w[7];
+
+ tweak[1] &= ~SKEIN_T1_FLAG_FIRST;
+ } while (--blkCnt);
+
+ ctx->h.T[0] = tweak[0];
+ ctx->h.T[1] = tweak[1];
+}
+
+void Skein1024_Process_Block(struct skein1024_ctx *ctx, const u8 *blkPtr,
+ size_t blkCnt, size_t byteCntAdd)
+{
+ struct threefish_key key;
+ u64 tweak[2];
+ int i;
+ u64 words[3];
+ u64 w[SKEIN1024_STATE_WORDS]; /* local copy of input block */
+
+ Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */
+ tweak[0] = ctx->h.T[0];
+ tweak[1] = ctx->h.T[1];
+
+ do {
+ u64 carry = byteCntAdd;
+
+ words[0] = tweak[0] & 0xffffffffL;
+ words[1] = ((tweak[0] >> 32) & 0xffffffffL);
+ words[2] = (tweak[1] & 0xffffffffL);
+
+ for (i = 0; i < 3; i++) {
+ carry += words[i];
+ words[i] = carry;
+ carry >>= 32;
+ }
+ tweak[0] = words[0] & 0xffffffffL;
+ tweak[0] |= (words[1] & 0xffffffffL) << 32;
+ tweak[1] |= words[2] & 0xffffffffL;
+
+ threefishSetKey(&key, Threefish1024, ctx->X, tweak);
+
+ /* get input block in little-endian format */
+ Skein_Get64_LSB_First(w, blkPtr, SKEIN1024_STATE_WORDS);
+
+ threefishEncryptBlockWords(&key, w, ctx->X);
+
+ blkPtr += SKEIN1024_BLOCK_BYTES;
+
+ /* do the final "feedforward" xor, update ctx chaining vars */
+ ctx->X[0] = ctx->X[0] ^ w[0];
+ ctx->X[1] = ctx->X[1] ^ w[1];
+ ctx->X[2] = ctx->X[2] ^ w[2];
+ ctx->X[3] = ctx->X[3] ^ w[3];
+ ctx->X[4] = ctx->X[4] ^ w[4];
+ ctx->X[5] = ctx->X[5] ^ w[5];
+ ctx->X[6] = ctx->X[6] ^ w[6];
+ ctx->X[7] = ctx->X[7] ^ w[7];
+ ctx->X[8] = ctx->X[8] ^ w[8];
+ ctx->X[9] = ctx->X[9] ^ w[9];
+ ctx->X[10] = ctx->X[10] ^ w[10];
+ ctx->X[11] = ctx->X[11] ^ w[11];
+ ctx->X[12] = ctx->X[12] ^ w[12];
+ ctx->X[13] = ctx->X[13] ^ w[13];
+ ctx->X[14] = ctx->X[14] ^ w[14];
+ ctx->X[15] = ctx->X[15] ^ w[15];
+
+ tweak[1] &= ~SKEIN_T1_FLAG_FIRST;
+ } while (--blkCnt);
+
+ ctx->h.T[0] = tweak[0];
+ ctx->h.T[1] = tweak[1];
+}
--- /dev/null
+/***********************************************************************
+**
+** Implementation of the Skein block functions.
+**
+** Source code author: Doug Whiting, 2008.
+**
+** This algorithm and source code is released to the public domain.
+**
+** Compile-time switches:
+**
+** SKEIN_USE_ASM -- set bits (256/512/1024) to select which
+** versions use ASM code for block processing
+** [default: use C for all block sizes]
+**
+************************************************************************/
+
+#include <linux/string.h>
+#include <skein.h>
+
+#ifndef SKEIN_USE_ASM
+#define SKEIN_USE_ASM (0) /* default is all C code (no ASM) */
+#endif
+
+#ifndef SKEIN_LOOP
+#define SKEIN_LOOP 001 /* default: unroll 256 and 512, but not 1024 */
+#endif
+
+#define BLK_BITS (WCNT*64) /* some useful definitions for code here */
+#define KW_TWK_BASE (0)
+#define KW_KEY_BASE (3)
+#define ks (kw + KW_KEY_BASE)
+#define ts (kw + KW_TWK_BASE)
+
+#ifdef SKEIN_DEBUG
+#define DebugSaveTweak(ctx) { ctx->h.T[0] = ts[0]; ctx->h.T[1] = ts[1]; }
+#else
+#define DebugSaveTweak(ctx)
+#endif
+
+/***************************** Skein_256 ******************************/
+#if !(SKEIN_USE_ASM & 256)
+void Skein_256_Process_Block(struct skein_256_ctx *ctx, const u8 *blkPtr,
+ size_t blkCnt, size_t byteCntAdd)
+ { /* do it in C */
+ enum {
+ WCNT = SKEIN_256_STATE_WORDS
+ };
+#undef RCNT
+#define RCNT (SKEIN_256_ROUNDS_TOTAL/8)
+
+#ifdef SKEIN_LOOP /* configure how much to unroll the loop */
+#define SKEIN_UNROLL_256 (((SKEIN_LOOP)/100)%10)
+#else
+#define SKEIN_UNROLL_256 (0)
+#endif
+
+#if SKEIN_UNROLL_256
+#if (RCNT % SKEIN_UNROLL_256)
+#error "Invalid SKEIN_UNROLL_256" /* sanity check on unroll count */
+#endif
+ size_t r;
+ u64 kw[WCNT+4+RCNT*2]; /* key schedule: chaining vars + tweak + "rot"*/
+#else
+ u64 kw[WCNT+4]; /* key schedule words : chaining vars + tweak */
+#endif
+ u64 X0, X1, X2, X3; /* local copy of context vars, for speed */
+ u64 w[WCNT]; /* local copy of input block */
+#ifdef SKEIN_DEBUG
+ const u64 *Xptr[4]; /* use for debugging (help cc put Xn in regs) */
+ Xptr[0] = &X0; Xptr[1] = &X1; Xptr[2] = &X2; Xptr[3] = &X3;
+#endif
+ Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */
+ ts[0] = ctx->h.T[0];
+ ts[1] = ctx->h.T[1];
+ do {
+ /*
+ * this implementation only supports 2**64 input bytes
+ * (no carry out here)
+ */
+ ts[0] += byteCntAdd; /* update processed length */
+
+ /* precompute the key schedule for this block */
+ ks[0] = ctx->X[0];
+ ks[1] = ctx->X[1];
+ ks[2] = ctx->X[2];
+ ks[3] = ctx->X[3];
+ ks[4] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ SKEIN_KS_PARITY;
+
+ ts[2] = ts[0] ^ ts[1];
+
+ /* get input block in little-endian format */
+ Skein_Get64_LSB_First(w, blkPtr, WCNT);
+ DebugSaveTweak(ctx);
+ Skein_Show_Block(BLK_BITS, &ctx->h, ctx->X, blkPtr, w, ks, ts);
+
+ X0 = w[0] + ks[0]; /* do the first full key injection */
+ X1 = w[1] + ks[1] + ts[0];
+ X2 = w[2] + ks[2] + ts[1];
+ X3 = w[3] + ks[3];
+
+ /* show starting state values */
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL,
+ Xptr);
+
+ blkPtr += SKEIN_256_BLOCK_BYTES;
+
+ /* run the rounds */
+
+#define Round256(p0, p1, p2, p3, ROT, rNum) \
+do { \
+ X##p0 += X##p1; X##p1 = RotL_64(X##p1, ROT##_0); X##p1 ^= X##p0; \
+ X##p2 += X##p3; X##p3 = RotL_64(X##p3, ROT##_1); X##p3 ^= X##p2; \
+} while (0)
+
+#if SKEIN_UNROLL_256 == 0
+#define R256(p0, p1, p2, p3, ROT, rNum) /* fully unrolled */ \
+do { \
+ Round256(p0, p1, p2, p3, ROT, rNum) \
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, rNum, Xptr); \
+} while (0)
+
+#define I256(R) \
+do { \
+ /* inject the key schedule value */ \
+ X0 += ks[((R)+1) % 5]; \
+ X1 += ks[((R)+2) % 5] + ts[((R)+1) % 3]; \
+ X2 += ks[((R)+3) % 5] + ts[((R)+2) % 3]; \
+ X3 += ks[((R)+4) % 5] + (R)+1; \
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, Xptr); \
+} while (0)
+#else /* looping version */
+#define R256(p0, p1, p2, p3, ROT, rNum) \
+do { \
+ Round256(p0, p1, p2, p3, ROT, rNum) \
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + rNum, Xptr); \
+} while (0)
+
+#define I256(R) \
+do { \
+ /* inject the key schedule value */ \
+ X0 += ks[r+(R)+0]; \
+ X1 += ks[r+(R)+1] + ts[r+(R)+0]; \
+ X2 += ks[r+(R)+2] + ts[r+(R)+1]; \
+ X3 += ks[r+(R)+3] + r+(R); \
+ /* rotate key schedule */ \
+ ks[r + (R) + 4] = ks[r + (R) - 1]; \
+ ts[r + (R) + 2] = ts[r + (R) - 1]; \
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, Xptr); \
+} while (0)
+
+ for (r = 1; r < 2 * RCNT; r += 2 * SKEIN_UNROLL_256)
+#endif
+ {
+#define R256_8_rounds(R) \
+do { \
+ R256(0, 1, 2, 3, R_256_0, 8 * (R) + 1); \
+ R256(0, 3, 2, 1, R_256_1, 8 * (R) + 2); \
+ R256(0, 1, 2, 3, R_256_2, 8 * (R) + 3); \
+ R256(0, 3, 2, 1, R_256_3, 8 * (R) + 4); \
+ I256(2 * (R)); \
+ R256(0, 1, 2, 3, R_256_4, 8 * (R) + 5); \
+ R256(0, 3, 2, 1, R_256_5, 8 * (R) + 6); \
+ R256(0, 1, 2, 3, R_256_6, 8 * (R) + 7); \
+ R256(0, 3, 2, 1, R_256_7, 8 * (R) + 8); \
+ I256(2 * (R) + 1); \
+} while (0)
+
+ R256_8_rounds(0);
+
+#define R256_Unroll_R(NN) \
+ ((SKEIN_UNROLL_256 == 0 && \
+ SKEIN_256_ROUNDS_TOTAL/8 > (NN)) || \
+ (SKEIN_UNROLL_256 > (NN)))
+
+ #if R256_Unroll_R(1)
+ R256_8_rounds(1);
+ #endif
+ #if R256_Unroll_R(2)
+ R256_8_rounds(2);
+ #endif
+ #if R256_Unroll_R(3)
+ R256_8_rounds(3);
+ #endif
+ #if R256_Unroll_R(4)
+ R256_8_rounds(4);
+ #endif
+ #if R256_Unroll_R(5)
+ R256_8_rounds(5);
+ #endif
+ #if R256_Unroll_R(6)
+ R256_8_rounds(6);
+ #endif
+ #if R256_Unroll_R(7)
+ R256_8_rounds(7);
+ #endif
+ #if R256_Unroll_R(8)
+ R256_8_rounds(8);
+ #endif
+ #if R256_Unroll_R(9)
+ R256_8_rounds(9);
+ #endif
+ #if R256_Unroll_R(10)
+ R256_8_rounds(10);
+ #endif
+ #if R256_Unroll_R(11)
+ R256_8_rounds(11);
+ #endif
+ #if R256_Unroll_R(12)
+ R256_8_rounds(12);
+ #endif
+ #if R256_Unroll_R(13)
+ R256_8_rounds(13);
+ #endif
+ #if R256_Unroll_R(14)
+ R256_8_rounds(14);
+ #endif
+ #if (SKEIN_UNROLL_256 > 14)
+#error "need more unrolling in Skein_256_Process_Block"
+ #endif
+ }
+ /* do the final "feedforward" xor, update context chaining */
+ ctx->X[0] = X0 ^ w[0];
+ ctx->X[1] = X1 ^ w[1];
+ ctx->X[2] = X2 ^ w[2];
+ ctx->X[3] = X3 ^ w[3];
+
+ Skein_Show_Round(BLK_BITS, &ctx->h, SKEIN_RND_FEED_FWD, ctx->X);
+
+ ts[1] &= ~SKEIN_T1_FLAG_FIRST;
+ } while (--blkCnt);
+ ctx->h.T[0] = ts[0];
+ ctx->h.T[1] = ts[1];
+}
+
+#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
+size_t Skein_256_Process_Block_CodeSize(void)
+{
+ return ((u8 *) Skein_256_Process_Block_CodeSize) -
+ ((u8 *) Skein_256_Process_Block);
+}
+unsigned int Skein_256_Unroll_Cnt(void)
+{
+ return SKEIN_UNROLL_256;
+}
+#endif
+#endif
+
+/***************************** Skein_512 ******************************/
+#if !(SKEIN_USE_ASM & 512)
+void Skein_512_Process_Block(struct skein_512_ctx *ctx, const u8 *blkPtr,
+ size_t blkCnt, size_t byteCntAdd)
+{ /* do it in C */
+ enum {
+ WCNT = SKEIN_512_STATE_WORDS
+ };
+#undef RCNT
+#define RCNT (SKEIN_512_ROUNDS_TOTAL/8)
+
+#ifdef SKEIN_LOOP /* configure how much to unroll the loop */
+#define SKEIN_UNROLL_512 (((SKEIN_LOOP)/10)%10)
+#else
+#define SKEIN_UNROLL_512 (0)
+#endif
+
+#if SKEIN_UNROLL_512
+#if (RCNT % SKEIN_UNROLL_512)
+#error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */
+#endif
+ size_t r;
+ u64 kw[WCNT+4+RCNT*2]; /* key sched: chaining vars + tweak + "rot"*/
+#else
+ u64 kw[WCNT+4]; /* key schedule words : chaining vars + tweak */
+#endif
+ u64 X0, X1, X2, X3, X4, X5, X6, X7; /* local copies, for speed */
+ u64 w[WCNT]; /* local copy of input block */
+#ifdef SKEIN_DEBUG
+ const u64 *Xptr[8]; /* use for debugging (help cc put Xn in regs) */
+ Xptr[0] = &X0; Xptr[1] = &X1; Xptr[2] = &X2; Xptr[3] = &X3;
+ Xptr[4] = &X4; Xptr[5] = &X5; Xptr[6] = &X6; Xptr[7] = &X7;
+#endif
+
+ Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */
+ ts[0] = ctx->h.T[0];
+ ts[1] = ctx->h.T[1];
+ do {
+ /*
+ * this implementation only supports 2**64 input bytes
+ * (no carry out here)
+ */
+ ts[0] += byteCntAdd; /* update processed length */
+
+ /* precompute the key schedule for this block */
+ ks[0] = ctx->X[0];
+ ks[1] = ctx->X[1];
+ ks[2] = ctx->X[2];
+ ks[3] = ctx->X[3];
+ ks[4] = ctx->X[4];
+ ks[5] = ctx->X[5];
+ ks[6] = ctx->X[6];
+ ks[7] = ctx->X[7];
+ ks[8] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^
+ ks[4] ^ ks[5] ^ ks[6] ^ ks[7] ^ SKEIN_KS_PARITY;
+
+ ts[2] = ts[0] ^ ts[1];
+
+ /* get input block in little-endian format */
+ Skein_Get64_LSB_First(w, blkPtr, WCNT);
+ DebugSaveTweak(ctx);
+ Skein_Show_Block(BLK_BITS, &ctx->h, ctx->X, blkPtr, w, ks, ts);
+
+ X0 = w[0] + ks[0]; /* do the first full key injection */
+ X1 = w[1] + ks[1];
+ X2 = w[2] + ks[2];
+ X3 = w[3] + ks[3];
+ X4 = w[4] + ks[4];
+ X5 = w[5] + ks[5] + ts[0];
+ X6 = w[6] + ks[6] + ts[1];
+ X7 = w[7] + ks[7];
+
+ blkPtr += SKEIN_512_BLOCK_BYTES;
+
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL,
+ Xptr);
+ /* run the rounds */
+#define Round512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, rNum) \
+do { \
+ X##p0 += X##p1; X##p1 = RotL_64(X##p1, ROT##_0); X##p1 ^= X##p0; \
+ X##p2 += X##p3; X##p3 = RotL_64(X##p3, ROT##_1); X##p3 ^= X##p2; \
+ X##p4 += X##p5; X##p5 = RotL_64(X##p5, ROT##_2); X##p5 ^= X##p4; \
+ X##p6 += X##p7; X##p7 = RotL_64(X##p7, ROT##_3); X##p7 ^= X##p6; \
+} while (0)
+
+#if SKEIN_UNROLL_512 == 0
+#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, rNum) /* unrolled */ \
+do { \
+ Round512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, rNum) \
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, rNum, Xptr); \
+} while (0)
+
+#define I512(R) \
+do { \
+ /* inject the key schedule value */ \
+ X0 += ks[((R) + 1) % 9]; \
+ X1 += ks[((R) + 2) % 9]; \
+ X2 += ks[((R) + 3) % 9]; \
+ X3 += ks[((R) + 4) % 9]; \
+ X4 += ks[((R) + 5) % 9]; \
+ X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \
+ X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \
+ X7 += ks[((R) + 8) % 9] + (R) + 1; \
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, Xptr); \
+} while (0)
+#else /* looping version */
+#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, rNum) \
+do { \
+ Round512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, rNum) \
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + rNum, Xptr); \
+} while (0)
+
+#define I512(R) \
+do { \
+ /* inject the key schedule value */ \
+ X0 += ks[r + (R) + 0]; \
+ X1 += ks[r + (R) + 1]; \
+ X2 += ks[r + (R) + 2]; \
+ X3 += ks[r + (R) + 3]; \
+ X4 += ks[r + (R) + 4]; \
+ X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \
+ X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \
+ X7 += ks[r + (R) + 7] + r + (R); \
+ /* rotate key schedule */ \
+ ks[r + (R) + 8] = ks[r + (R) - 1]; \
+ ts[r + (R) + 2] = ts[r + (R) - 1]; \
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, Xptr); \
+} while (0)
+
+ for (r = 1; r < 2 * RCNT; r += 2 * SKEIN_UNROLL_512)
+#endif /* end of looped code definitions */
+ {
+#define R512_8_rounds(R) /* do 8 full rounds */ \
+do { \
+ R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_0, 8 * (R) + 1); \
+ R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_1, 8 * (R) + 2); \
+ R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_2, 8 * (R) + 3); \
+ R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_3, 8 * (R) + 4); \
+ I512(2 * (R)); \
+ R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_4, 8 * (R) + 5); \
+ R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_5, 8 * (R) + 6); \
+ R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_6, 8 * (R) + 7); \
+ R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_7, 8 * (R) + 8); \
+ I512(2 * (R) + 1); /* and key injection */ \
+} while (0)
+
+ R512_8_rounds(0);
+
+#define R512_Unroll_R(NN) \
+ ((SKEIN_UNROLL_512 == 0 && \
+ SKEIN_512_ROUNDS_TOTAL/8 > (NN)) || \
+ (SKEIN_UNROLL_512 > (NN)))
+
+ #if R512_Unroll_R(1)
+ R512_8_rounds(1);
+ #endif
+ #if R512_Unroll_R(2)
+ R512_8_rounds(2);
+ #endif
+ #if R512_Unroll_R(3)
+ R512_8_rounds(3);
+ #endif
+ #if R512_Unroll_R(4)
+ R512_8_rounds(4);
+ #endif
+ #if R512_Unroll_R(5)
+ R512_8_rounds(5);
+ #endif
+ #if R512_Unroll_R(6)
+ R512_8_rounds(6);
+ #endif
+ #if R512_Unroll_R(7)
+ R512_8_rounds(7);
+ #endif
+ #if R512_Unroll_R(8)
+ R512_8_rounds(8);
+ #endif
+ #if R512_Unroll_R(9)
+ R512_8_rounds(9);
+ #endif
+ #if R512_Unroll_R(10)
+ R512_8_rounds(10);
+ #endif
+ #if R512_Unroll_R(11)
+ R512_8_rounds(11);
+ #endif
+ #if R512_Unroll_R(12)
+ R512_8_rounds(12);
+ #endif
+ #if R512_Unroll_R(13)
+ R512_8_rounds(13);
+ #endif
+ #if R512_Unroll_R(14)
+ R512_8_rounds(14);
+ #endif
+ #if (SKEIN_UNROLL_512 > 14)
+#error "need more unrolling in Skein_512_Process_Block"
+ #endif
+ }
+
+ /* do the final "feedforward" xor, update context chaining */
+ ctx->X[0] = X0 ^ w[0];
+ ctx->X[1] = X1 ^ w[1];
+ ctx->X[2] = X2 ^ w[2];
+ ctx->X[3] = X3 ^ w[3];
+ ctx->X[4] = X4 ^ w[4];
+ ctx->X[5] = X5 ^ w[5];
+ ctx->X[6] = X6 ^ w[6];
+ ctx->X[7] = X7 ^ w[7];
+ Skein_Show_Round(BLK_BITS, &ctx->h, SKEIN_RND_FEED_FWD, ctx->X);
+
+ ts[1] &= ~SKEIN_T1_FLAG_FIRST;
+ } while (--blkCnt);
+ ctx->h.T[0] = ts[0];
+ ctx->h.T[1] = ts[1];
+}
+
+#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
+size_t Skein_512_Process_Block_CodeSize(void)
+{
+ return ((u8 *) Skein_512_Process_Block_CodeSize) -
+ ((u8 *) Skein_512_Process_Block);
+}
+unsigned int Skein_512_Unroll_Cnt(void)
+{
+ return SKEIN_UNROLL_512;
+}
+#endif
+#endif
+
+/***************************** Skein1024 ******************************/
+#if !(SKEIN_USE_ASM & 1024)
+void Skein1024_Process_Block(struct skein1024_ctx *ctx, const u8 *blkPtr,
+ size_t blkCnt, size_t byteCntAdd)
+{ /* do it in C, always looping (unrolled is bigger AND slower!) */
+ enum {
+ WCNT = SKEIN1024_STATE_WORDS
+ };
+#undef RCNT
+#define RCNT (SKEIN1024_ROUNDS_TOTAL/8)
+
+#ifdef SKEIN_LOOP /* configure how much to unroll the loop */
+#define SKEIN_UNROLL_1024 ((SKEIN_LOOP)%10)
+#else
+#define SKEIN_UNROLL_1024 (0)
+#endif
+
+#if (SKEIN_UNROLL_1024 != 0)
+#if (RCNT % SKEIN_UNROLL_1024)
+#error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */
+#endif
+ size_t r;
+ u64 kw[WCNT+4+RCNT*2]; /* key sched: chaining vars + tweak + "rot" */
+#else
+ u64 kw[WCNT+4]; /* key schedule words : chaining vars + tweak */
+#endif
+
+ /* local copy of vars, for speed */
+ u64 X00, X01, X02, X03, X04, X05, X06, X07,
+ X08, X09, X10, X11, X12, X13, X14, X15;
+ u64 w[WCNT]; /* local copy of input block */
+#ifdef SKEIN_DEBUG
+ const u64 *Xptr[16]; /* use for debugging (help cc put Xn in regs) */
+ Xptr[0] = &X00; Xptr[1] = &X01; Xptr[2] = &X02; Xptr[3] = &X03;
+ Xptr[4] = &X04; Xptr[5] = &X05; Xptr[6] = &X06; Xptr[7] = &X07;
+ Xptr[8] = &X08; Xptr[9] = &X09; Xptr[10] = &X10; Xptr[11] = &X11;
+ Xptr[12] = &X12; Xptr[13] = &X13; Xptr[14] = &X14; Xptr[15] = &X15;
+#endif
+
+ Skein_assert(blkCnt != 0); /* never call with blkCnt == 0! */
+ ts[0] = ctx->h.T[0];
+ ts[1] = ctx->h.T[1];
+ do {
+ /*
+ * this implementation only supports 2**64 input bytes
+ * (no carry out here)
+ */
+ ts[0] += byteCntAdd; /* update processed length */
+
+ /* precompute the key schedule for this block */
+ ks[0] = ctx->X[0];
+ ks[1] = ctx->X[1];
+ ks[2] = ctx->X[2];
+ ks[3] = ctx->X[3];
+ ks[4] = ctx->X[4];
+ ks[5] = ctx->X[5];
+ ks[6] = ctx->X[6];
+ ks[7] = ctx->X[7];
+ ks[8] = ctx->X[8];
+ ks[9] = ctx->X[9];
+ ks[10] = ctx->X[10];
+ ks[11] = ctx->X[11];
+ ks[12] = ctx->X[12];
+ ks[13] = ctx->X[13];
+ ks[14] = ctx->X[14];
+ ks[15] = ctx->X[15];
+ ks[16] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^
+ ks[4] ^ ks[5] ^ ks[6] ^ ks[7] ^
+ ks[8] ^ ks[9] ^ ks[10] ^ ks[11] ^
+ ks[12] ^ ks[13] ^ ks[14] ^ ks[15] ^ SKEIN_KS_PARITY;
+
+ ts[2] = ts[0] ^ ts[1];
+
+ /* get input block in little-endian format */
+ Skein_Get64_LSB_First(w, blkPtr, WCNT);
+ DebugSaveTweak(ctx);
+ Skein_Show_Block(BLK_BITS, &ctx->h, ctx->X, blkPtr, w, ks, ts);
+
+ X00 = w[0] + ks[0]; /* do the first full key injection */
+ X01 = w[1] + ks[1];
+ X02 = w[2] + ks[2];
+ X03 = w[3] + ks[3];
+ X04 = w[4] + ks[4];
+ X05 = w[5] + ks[5];
+ X06 = w[6] + ks[6];
+ X07 = w[7] + ks[7];
+ X08 = w[8] + ks[8];
+ X09 = w[9] + ks[9];
+ X10 = w[10] + ks[10];
+ X11 = w[11] + ks[11];
+ X12 = w[12] + ks[12];
+ X13 = w[13] + ks[13] + ts[0];
+ X14 = w[14] + ks[14] + ts[1];
+ X15 = w[15] + ks[15];
+
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INITIAL,
+ Xptr);
+
+#define Round1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
+ pF, ROT, rNum) \
+do { \
+ X##p0 += X##p1; X##p1 = RotL_64(X##p1, ROT##_0); X##p1 ^= X##p0; \
+ X##p2 += X##p3; X##p3 = RotL_64(X##p3, ROT##_1); X##p3 ^= X##p2; \
+ X##p4 += X##p5; X##p5 = RotL_64(X##p5, ROT##_2); X##p5 ^= X##p4; \
+ X##p6 += X##p7; X##p7 = RotL_64(X##p7, ROT##_3); X##p7 ^= X##p6; \
+ X##p8 += X##p9; X##p9 = RotL_64(X##p9, ROT##_4); X##p9 ^= X##p8; \
+ X##pA += X##pB; X##pB = RotL_64(X##pB, ROT##_5); X##pB ^= X##pA; \
+ X##pC += X##pD; X##pD = RotL_64(X##pD, ROT##_6); X##pD ^= X##pC; \
+ X##pE += X##pF; X##pF = RotL_64(X##pF, ROT##_7); X##pF ^= X##pE; \
+} while (0)
+
+#if SKEIN_UNROLL_1024 == 0
+#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \
+ ROT, rn) \
+do { \
+ Round1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
+ pF, ROT, rn) \
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, rn, Xptr); \
+} while (0)
+
+#define I1024(R) \
+do { \
+ /* inject the key schedule value */ \
+ X00 += ks[((R) + 1) % 17]; \
+ X01 += ks[((R) + 2) % 17]; \
+ X02 += ks[((R) + 3) % 17]; \
+ X03 += ks[((R) + 4) % 17]; \
+ X04 += ks[((R) + 5) % 17]; \
+ X05 += ks[((R) + 6) % 17]; \
+ X06 += ks[((R) + 7) % 17]; \
+ X07 += ks[((R) + 8) % 17]; \
+ X08 += ks[((R) + 9) % 17]; \
+ X09 += ks[((R) + 10) % 17]; \
+ X10 += ks[((R) + 11) % 17]; \
+ X11 += ks[((R) + 12) % 17]; \
+ X12 += ks[((R) + 13) % 17]; \
+ X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \
+ X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \
+ X15 += ks[((R) + 16) % 17] + (R) + 1; \
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, SKEIN_RND_KEY_INJECT, Xptr); \
+} while (0)
+#else /* looping version */
+#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \
+ ROT, rn) \
+do { \
+ Round1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
+ pF, ROT, rn) \
+ Skein_Show_R_Ptr(BLK_BITS, &ctx->h, 4 * (r - 1) + rn, Xptr); \
+} while (0)
+
+#define I1024(R) \
+do { \
+ /* inject the key schedule value */ \
+ X00 += ks[r + (R) + 0]; \
+ X01 += ks[r + (R) + 1]; \
+ X02 += ks[r + (R) + 2]; \
+ X03 += ks[r + (R) + 3]; \
+ X04 += ks[r + (R) + 4]; \
+ X05 += ks[r + (R) + 5]; \
+ X06 += ks[r + (R) + 6]; \
+ X07 += ks[r + (R) + 7]; \
+ X08 += ks[r + (R) + 8]; \
+ X09 += ks[r + (R) + 9]; \
+ X10 += ks[r + (R) + 10]; \
+ X11 += ks[r + (R) + 11]; \
+ X12 += ks[r + (R) + 12]; \
+ X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \
+ X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \
+ X15 += ks[r + (R) + 15] + r + (R); \
+ /* rotate key schedule */ \
+ ks[r + (R) + 16] = ks[r + (R) - 1]; \
+ ts[r + (R) + 2] = ts[r + (R) - 1]; \
+ Skein_Show_R_Ptr(BLK_BITSi, &ctx->h, SKEIN_RND_KEY_INJECT, Xptr); \
+} while (0)
+
+ for (r = 1; r <= 2 * RCNT; r += 2 * SKEIN_UNROLL_1024)
+#endif
+ {
+#define R1024_8_rounds(R) \
+do { \
+ R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, \
+ R1024_0, 8*(R) + 1); \
+ R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, 05, 08, 01, \
+ R1024_1, 8*(R) + 2); \
+ R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, 11, 10, 09, \
+ R1024_2, 8*(R) + 3); \
+ R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, 03, 12, 07, \
+ R1024_3, 8*(R) + 4); \
+ I1024(2*(R)); \
+ R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, \
+ R1024_4, 8*(R) + 5); \
+ R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, 05, 08, 01, \
+ R1024_5, 8*(R) + 6); \
+ R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, 11, 10, 09, \
+ R1024_6, 8*(R) + 7); \
+ R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, 03, 12, 07, \
+ R1024_7, 8*(R) + 8); \
+ I1024(2*(R)+1); \
+} while (0)
+
+ R1024_8_rounds(0);
+
+#define R1024_Unroll_R(NN) \
+ ((SKEIN_UNROLL_1024 == 0 && \
+ SKEIN1024_ROUNDS_TOTAL/8 > (NN)) || \
+ (SKEIN_UNROLL_1024 > (NN)))
+
+ #if R1024_Unroll_R(1)
+ R1024_8_rounds(1);
+ #endif
+ #if R1024_Unroll_R(2)
+ R1024_8_rounds(2);
+ #endif
+ #if R1024_Unroll_R(3)
+ R1024_8_rounds(3);
+ #endif
+ #if R1024_Unroll_R(4)
+ R1024_8_rounds(4);
+ #endif
+ #if R1024_Unroll_R(5)
+ R1024_8_rounds(5);
+ #endif
+ #if R1024_Unroll_R(6)
+ R1024_8_rounds(6);
+ #endif
+ #if R1024_Unroll_R(7)
+ R1024_8_rounds(7);
+ #endif
+ #if R1024_Unroll_R(8)
+ R1024_8_rounds(8);
+ #endif
+ #if R1024_Unroll_R(9)
+ R1024_8_rounds(9);
+ #endif
+ #if R1024_Unroll_R(10)
+ R1024_8_rounds(10);
+ #endif
+ #if R1024_Unroll_R(11)
+ R1024_8_rounds(11);
+ #endif
+ #if R1024_Unroll_R(12)
+ R1024_8_rounds(12);
+ #endif
+ #if R1024_Unroll_R(13)
+ R1024_8_rounds(13);
+ #endif
+ #if R1024_Unroll_R(14)
+ R1024_8_rounds(14);
+ #endif
+#if (SKEIN_UNROLL_1024 > 14)
+#error "need more unrolling in Skein_1024_Process_Block"
+ #endif
+ }
+ /* do the final "feedforward" xor, update context chaining */
+
+ ctx->X[0] = X00 ^ w[0];
+ ctx->X[1] = X01 ^ w[1];
+ ctx->X[2] = X02 ^ w[2];
+ ctx->X[3] = X03 ^ w[3];
+ ctx->X[4] = X04 ^ w[4];
+ ctx->X[5] = X05 ^ w[5];
+ ctx->X[6] = X06 ^ w[6];
+ ctx->X[7] = X07 ^ w[7];
+ ctx->X[8] = X08 ^ w[8];
+ ctx->X[9] = X09 ^ w[9];
+ ctx->X[10] = X10 ^ w[10];
+ ctx->X[11] = X11 ^ w[11];
+ ctx->X[12] = X12 ^ w[12];
+ ctx->X[13] = X13 ^ w[13];
+ ctx->X[14] = X14 ^ w[14];
+ ctx->X[15] = X15 ^ w[15];
+
+ Skein_Show_Round(BLK_BITS, &ctx->h, SKEIN_RND_FEED_FWD, ctx->X);
+
+ ts[1] &= ~SKEIN_T1_FLAG_FIRST;
+ blkPtr += SKEIN1024_BLOCK_BYTES;
+ } while (--blkCnt);
+ ctx->h.T[0] = ts[0];
+ ctx->h.T[1] = ts[1];
+}
+
+#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
+size_t Skein1024_Process_Block_CodeSize(void)
+{
+ return ((u8 *) Skein1024_Process_Block_CodeSize) -
+ ((u8 *) Skein1024_Process_Block);
+}
+unsigned int Skein1024_Unroll_Cnt(void)
+{
+ return SKEIN_UNROLL_1024;
+}
+#endif
+#endif
--- /dev/null
+#include <linux/string.h>
+#include <threefishApi.h>
+
+
+void threefishEncrypt1024(struct threefish_key *keyCtx, u64 *input, u64 *output)
+{
+ u64 b0 = input[0], b1 = input[1],
+ b2 = input[2], b3 = input[3],
+ b4 = input[4], b5 = input[5],
+ b6 = input[6], b7 = input[7],
+ b8 = input[8], b9 = input[9],
+ b10 = input[10], b11 = input[11],
+ b12 = input[12], b13 = input[13],
+ b14 = input[14], b15 = input[15];
+ u64 k0 = keyCtx->key[0], k1 = keyCtx->key[1],
+ k2 = keyCtx->key[2], k3 = keyCtx->key[3],
+ k4 = keyCtx->key[4], k5 = keyCtx->key[5],
+ k6 = keyCtx->key[6], k7 = keyCtx->key[7],
+ k8 = keyCtx->key[8], k9 = keyCtx->key[9],
+ k10 = keyCtx->key[10], k11 = keyCtx->key[11],
+ k12 = keyCtx->key[12], k13 = keyCtx->key[13],
+ k14 = keyCtx->key[14], k15 = keyCtx->key[15],
+ k16 = keyCtx->key[16];
+ u64 t0 = keyCtx->tweak[0], t1 = keyCtx->tweak[1],
+ t2 = keyCtx->tweak[2];
+
+ b1 += k1;
+ b0 += b1 + k0;
+ b1 = ((b1 << 24) | (b1 >> (64 - 24))) ^ b0;
+
+ b3 += k3;
+ b2 += b3 + k2;
+ b3 = ((b3 << 13) | (b3 >> (64 - 13))) ^ b2;
+
+ b5 += k5;
+ b4 += b5 + k4;
+ b5 = ((b5 << 8) | (b5 >> (64 - 8))) ^ b4;
+
+ b7 += k7;
+ b6 += b7 + k6;
+ b7 = ((b7 << 47) | (b7 >> (64 - 47))) ^ b6;
+
+ b9 += k9;
+ b8 += b9 + k8;
+ b9 = ((b9 << 8) | (b9 >> (64 - 8))) ^ b8;
+
+ b11 += k11;
+ b10 += b11 + k10;
+ b11 = ((b11 << 17) | (b11 >> (64 - 17))) ^ b10;
+
+ b13 += k13 + t0;
+ b12 += b13 + k12;
+ b13 = ((b13 << 22) | (b13 >> (64 - 22))) ^ b12;
+
+ b15 += k15;
+ b14 += b15 + k14 + t1;
+ b15 = ((b15 << 37) | (b15 >> (64 - 37))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 38) | (b9 >> (64 - 38))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 19) | (b13 >> (64 - 19))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 10) | (b11 >> (64 - 10))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 55) | (b15 >> (64 - 55))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 49) | (b7 >> (64 - 49))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 18) | (b3 >> (64 - 18))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 23) | (b5 >> (64 - 23))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 52) | (b1 >> (64 - 52))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 33) | (b7 >> (64 - 33))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 4) | (b5 >> (64 - 4))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 51) | (b3 >> (64 - 51))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 34) | (b15 >> (64 - 34))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 41) | (b13 >> (64 - 41))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 59) | (b11 >> (64 - 59))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 17) | (b9 >> (64 - 17))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 5) | (b15 >> (64 - 5))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 20) | (b11 >> (64 - 20))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 48) | (b13 >> (64 - 48))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 41) | (b9 >> (64 - 41))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 47) | (b1 >> (64 - 47))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 28) | (b5 >> (64 - 28))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 25) | (b7 >> (64 - 25))) ^ b12;
+
+ b1 += k2;
+ b0 += b1 + k1;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b0;
+
+ b3 += k4;
+ b2 += b3 + k3;
+ b3 = ((b3 << 9) | (b3 >> (64 - 9))) ^ b2;
+
+ b5 += k6;
+ b4 += b5 + k5;
+ b5 = ((b5 << 37) | (b5 >> (64 - 37))) ^ b4;
+
+ b7 += k8;
+ b6 += b7 + k7;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b6;
+
+ b9 += k10;
+ b8 += b9 + k9;
+ b9 = ((b9 << 12) | (b9 >> (64 - 12))) ^ b8;
+
+ b11 += k12;
+ b10 += b11 + k11;
+ b11 = ((b11 << 47) | (b11 >> (64 - 47))) ^ b10;
+
+ b13 += k14 + t1;
+ b12 += b13 + k13;
+ b13 = ((b13 << 44) | (b13 >> (64 - 44))) ^ b12;
+
+ b15 += k16 + 1;
+ b14 += b15 + k15 + t2;
+ b15 = ((b15 << 30) | (b15 >> (64 - 30))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 16) | (b9 >> (64 - 16))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 34) | (b13 >> (64 - 34))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 56) | (b11 >> (64 - 56))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 51) | (b15 >> (64 - 51))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 4) | (b7 >> (64 - 4))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 53) | (b3 >> (64 - 53))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 42) | (b5 >> (64 - 42))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 44) | (b5 >> (64 - 44))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 47) | (b3 >> (64 - 47))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 19) | (b15 >> (64 - 19))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 42) | (b13 >> (64 - 42))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 44) | (b11 >> (64 - 44))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 25) | (b9 >> (64 - 25))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 9) | (b15 >> (64 - 9))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 48) | (b11 >> (64 - 48))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 35) | (b13 >> (64 - 35))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 52) | (b9 >> (64 - 52))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 31) | (b5 >> (64 - 31))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 37) | (b3 >> (64 - 37))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 20) | (b7 >> (64 - 20))) ^ b12;
+
+ b1 += k3;
+ b0 += b1 + k2;
+ b1 = ((b1 << 24) | (b1 >> (64 - 24))) ^ b0;
+
+ b3 += k5;
+ b2 += b3 + k4;
+ b3 = ((b3 << 13) | (b3 >> (64 - 13))) ^ b2;
+
+ b5 += k7;
+ b4 += b5 + k6;
+ b5 = ((b5 << 8) | (b5 >> (64 - 8))) ^ b4;
+
+ b7 += k9;
+ b6 += b7 + k8;
+ b7 = ((b7 << 47) | (b7 >> (64 - 47))) ^ b6;
+
+ b9 += k11;
+ b8 += b9 + k10;
+ b9 = ((b9 << 8) | (b9 >> (64 - 8))) ^ b8;
+
+ b11 += k13;
+ b10 += b11 + k12;
+ b11 = ((b11 << 17) | (b11 >> (64 - 17))) ^ b10;
+
+ b13 += k15 + t2;
+ b12 += b13 + k14;
+ b13 = ((b13 << 22) | (b13 >> (64 - 22))) ^ b12;
+
+ b15 += k0 + 2;
+ b14 += b15 + k16 + t0;
+ b15 = ((b15 << 37) | (b15 >> (64 - 37))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 38) | (b9 >> (64 - 38))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 19) | (b13 >> (64 - 19))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 10) | (b11 >> (64 - 10))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 55) | (b15 >> (64 - 55))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 49) | (b7 >> (64 - 49))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 18) | (b3 >> (64 - 18))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 23) | (b5 >> (64 - 23))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 52) | (b1 >> (64 - 52))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 33) | (b7 >> (64 - 33))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 4) | (b5 >> (64 - 4))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 51) | (b3 >> (64 - 51))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 34) | (b15 >> (64 - 34))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 41) | (b13 >> (64 - 41))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 59) | (b11 >> (64 - 59))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 17) | (b9 >> (64 - 17))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 5) | (b15 >> (64 - 5))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 20) | (b11 >> (64 - 20))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 48) | (b13 >> (64 - 48))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 41) | (b9 >> (64 - 41))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 47) | (b1 >> (64 - 47))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 28) | (b5 >> (64 - 28))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 25) | (b7 >> (64 - 25))) ^ b12;
+
+ b1 += k4;
+ b0 += b1 + k3;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b0;
+
+ b3 += k6;
+ b2 += b3 + k5;
+ b3 = ((b3 << 9) | (b3 >> (64 - 9))) ^ b2;
+
+ b5 += k8;
+ b4 += b5 + k7;
+ b5 = ((b5 << 37) | (b5 >> (64 - 37))) ^ b4;
+
+ b7 += k10;
+ b6 += b7 + k9;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b6;
+
+ b9 += k12;
+ b8 += b9 + k11;
+ b9 = ((b9 << 12) | (b9 >> (64 - 12))) ^ b8;
+
+ b11 += k14;
+ b10 += b11 + k13;
+ b11 = ((b11 << 47) | (b11 >> (64 - 47))) ^ b10;
+
+ b13 += k16 + t0;
+ b12 += b13 + k15;
+ b13 = ((b13 << 44) | (b13 >> (64 - 44))) ^ b12;
+
+ b15 += k1 + 3;
+ b14 += b15 + k0 + t1;
+ b15 = ((b15 << 30) | (b15 >> (64 - 30))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 16) | (b9 >> (64 - 16))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 34) | (b13 >> (64 - 34))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 56) | (b11 >> (64 - 56))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 51) | (b15 >> (64 - 51))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 4) | (b7 >> (64 - 4))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 53) | (b3 >> (64 - 53))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 42) | (b5 >> (64 - 42))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 44) | (b5 >> (64 - 44))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 47) | (b3 >> (64 - 47))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 19) | (b15 >> (64 - 19))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 42) | (b13 >> (64 - 42))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 44) | (b11 >> (64 - 44))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 25) | (b9 >> (64 - 25))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 9) | (b15 >> (64 - 9))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 48) | (b11 >> (64 - 48))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 35) | (b13 >> (64 - 35))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 52) | (b9 >> (64 - 52))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 31) | (b5 >> (64 - 31))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 37) | (b3 >> (64 - 37))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 20) | (b7 >> (64 - 20))) ^ b12;
+
+ b1 += k5;
+ b0 += b1 + k4;
+ b1 = ((b1 << 24) | (b1 >> (64 - 24))) ^ b0;
+
+ b3 += k7;
+ b2 += b3 + k6;
+ b3 = ((b3 << 13) | (b3 >> (64 - 13))) ^ b2;
+
+ b5 += k9;
+ b4 += b5 + k8;
+ b5 = ((b5 << 8) | (b5 >> (64 - 8))) ^ b4;
+
+ b7 += k11;
+ b6 += b7 + k10;
+ b7 = ((b7 << 47) | (b7 >> (64 - 47))) ^ b6;
+
+ b9 += k13;
+ b8 += b9 + k12;
+ b9 = ((b9 << 8) | (b9 >> (64 - 8))) ^ b8;
+
+ b11 += k15;
+ b10 += b11 + k14;
+ b11 = ((b11 << 17) | (b11 >> (64 - 17))) ^ b10;
+
+ b13 += k0 + t1;
+ b12 += b13 + k16;
+ b13 = ((b13 << 22) | (b13 >> (64 - 22))) ^ b12;
+
+ b15 += k2 + 4;
+ b14 += b15 + k1 + t2;
+ b15 = ((b15 << 37) | (b15 >> (64 - 37))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 38) | (b9 >> (64 - 38))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 19) | (b13 >> (64 - 19))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 10) | (b11 >> (64 - 10))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 55) | (b15 >> (64 - 55))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 49) | (b7 >> (64 - 49))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 18) | (b3 >> (64 - 18))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 23) | (b5 >> (64 - 23))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 52) | (b1 >> (64 - 52))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 33) | (b7 >> (64 - 33))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 4) | (b5 >> (64 - 4))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 51) | (b3 >> (64 - 51))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 34) | (b15 >> (64 - 34))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 41) | (b13 >> (64 - 41))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 59) | (b11 >> (64 - 59))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 17) | (b9 >> (64 - 17))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 5) | (b15 >> (64 - 5))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 20) | (b11 >> (64 - 20))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 48) | (b13 >> (64 - 48))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 41) | (b9 >> (64 - 41))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 47) | (b1 >> (64 - 47))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 28) | (b5 >> (64 - 28))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 25) | (b7 >> (64 - 25))) ^ b12;
+
+ b1 += k6;
+ b0 += b1 + k5;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b0;
+
+ b3 += k8;
+ b2 += b3 + k7;
+ b3 = ((b3 << 9) | (b3 >> (64 - 9))) ^ b2;
+
+ b5 += k10;
+ b4 += b5 + k9;
+ b5 = ((b5 << 37) | (b5 >> (64 - 37))) ^ b4;
+
+ b7 += k12;
+ b6 += b7 + k11;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b6;
+
+ b9 += k14;
+ b8 += b9 + k13;
+ b9 = ((b9 << 12) | (b9 >> (64 - 12))) ^ b8;
+
+ b11 += k16;
+ b10 += b11 + k15;
+ b11 = ((b11 << 47) | (b11 >> (64 - 47))) ^ b10;
+
+ b13 += k1 + t2;
+ b12 += b13 + k0;
+ b13 = ((b13 << 44) | (b13 >> (64 - 44))) ^ b12;
+
+ b15 += k3 + 5;
+ b14 += b15 + k2 + t0;
+ b15 = ((b15 << 30) | (b15 >> (64 - 30))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 16) | (b9 >> (64 - 16))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 34) | (b13 >> (64 - 34))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 56) | (b11 >> (64 - 56))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 51) | (b15 >> (64 - 51))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 4) | (b7 >> (64 - 4))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 53) | (b3 >> (64 - 53))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 42) | (b5 >> (64 - 42))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 44) | (b5 >> (64 - 44))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 47) | (b3 >> (64 - 47))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 19) | (b15 >> (64 - 19))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 42) | (b13 >> (64 - 42))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 44) | (b11 >> (64 - 44))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 25) | (b9 >> (64 - 25))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 9) | (b15 >> (64 - 9))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 48) | (b11 >> (64 - 48))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 35) | (b13 >> (64 - 35))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 52) | (b9 >> (64 - 52))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 31) | (b5 >> (64 - 31))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 37) | (b3 >> (64 - 37))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 20) | (b7 >> (64 - 20))) ^ b12;
+
+ b1 += k7;
+ b0 += b1 + k6;
+ b1 = ((b1 << 24) | (b1 >> (64 - 24))) ^ b0;
+
+ b3 += k9;
+ b2 += b3 + k8;
+ b3 = ((b3 << 13) | (b3 >> (64 - 13))) ^ b2;
+
+ b5 += k11;
+ b4 += b5 + k10;
+ b5 = ((b5 << 8) | (b5 >> (64 - 8))) ^ b4;
+
+ b7 += k13;
+ b6 += b7 + k12;
+ b7 = ((b7 << 47) | (b7 >> (64 - 47))) ^ b6;
+
+ b9 += k15;
+ b8 += b9 + k14;
+ b9 = ((b9 << 8) | (b9 >> (64 - 8))) ^ b8;
+
+ b11 += k0;
+ b10 += b11 + k16;
+ b11 = ((b11 << 17) | (b11 >> (64 - 17))) ^ b10;
+
+ b13 += k2 + t0;
+ b12 += b13 + k1;
+ b13 = ((b13 << 22) | (b13 >> (64 - 22))) ^ b12;
+
+ b15 += k4 + 6;
+ b14 += b15 + k3 + t1;
+ b15 = ((b15 << 37) | (b15 >> (64 - 37))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 38) | (b9 >> (64 - 38))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 19) | (b13 >> (64 - 19))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 10) | (b11 >> (64 - 10))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 55) | (b15 >> (64 - 55))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 49) | (b7 >> (64 - 49))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 18) | (b3 >> (64 - 18))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 23) | (b5 >> (64 - 23))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 52) | (b1 >> (64 - 52))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 33) | (b7 >> (64 - 33))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 4) | (b5 >> (64 - 4))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 51) | (b3 >> (64 - 51))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 34) | (b15 >> (64 - 34))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 41) | (b13 >> (64 - 41))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 59) | (b11 >> (64 - 59))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 17) | (b9 >> (64 - 17))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 5) | (b15 >> (64 - 5))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 20) | (b11 >> (64 - 20))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 48) | (b13 >> (64 - 48))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 41) | (b9 >> (64 - 41))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 47) | (b1 >> (64 - 47))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 28) | (b5 >> (64 - 28))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 25) | (b7 >> (64 - 25))) ^ b12;
+
+ b1 += k8;
+ b0 += b1 + k7;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b0;
+
+ b3 += k10;
+ b2 += b3 + k9;
+ b3 = ((b3 << 9) | (b3 >> (64 - 9))) ^ b2;
+
+ b5 += k12;
+ b4 += b5 + k11;
+ b5 = ((b5 << 37) | (b5 >> (64 - 37))) ^ b4;
+
+ b7 += k14;
+ b6 += b7 + k13;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b6;
+
+ b9 += k16;
+ b8 += b9 + k15;
+ b9 = ((b9 << 12) | (b9 >> (64 - 12))) ^ b8;
+
+ b11 += k1;
+ b10 += b11 + k0;
+ b11 = ((b11 << 47) | (b11 >> (64 - 47))) ^ b10;
+
+ b13 += k3 + t1;
+ b12 += b13 + k2;
+ b13 = ((b13 << 44) | (b13 >> (64 - 44))) ^ b12;
+
+ b15 += k5 + 7;
+ b14 += b15 + k4 + t2;
+ b15 = ((b15 << 30) | (b15 >> (64 - 30))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 16) | (b9 >> (64 - 16))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 34) | (b13 >> (64 - 34))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 56) | (b11 >> (64 - 56))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 51) | (b15 >> (64 - 51))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 4) | (b7 >> (64 - 4))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 53) | (b3 >> (64 - 53))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 42) | (b5 >> (64 - 42))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 44) | (b5 >> (64 - 44))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 47) | (b3 >> (64 - 47))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 19) | (b15 >> (64 - 19))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 42) | (b13 >> (64 - 42))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 44) | (b11 >> (64 - 44))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 25) | (b9 >> (64 - 25))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 9) | (b15 >> (64 - 9))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 48) | (b11 >> (64 - 48))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 35) | (b13 >> (64 - 35))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 52) | (b9 >> (64 - 52))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 31) | (b5 >> (64 - 31))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 37) | (b3 >> (64 - 37))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 20) | (b7 >> (64 - 20))) ^ b12;
+
+ b1 += k9;
+ b0 += b1 + k8;
+ b1 = ((b1 << 24) | (b1 >> (64 - 24))) ^ b0;
+
+ b3 += k11;
+ b2 += b3 + k10;
+ b3 = ((b3 << 13) | (b3 >> (64 - 13))) ^ b2;
+
+ b5 += k13;
+ b4 += b5 + k12;
+ b5 = ((b5 << 8) | (b5 >> (64 - 8))) ^ b4;
+
+ b7 += k15;
+ b6 += b7 + k14;
+ b7 = ((b7 << 47) | (b7 >> (64 - 47))) ^ b6;
+
+ b9 += k0;
+ b8 += b9 + k16;
+ b9 = ((b9 << 8) | (b9 >> (64 - 8))) ^ b8;
+
+ b11 += k2;
+ b10 += b11 + k1;
+ b11 = ((b11 << 17) | (b11 >> (64 - 17))) ^ b10;
+
+ b13 += k4 + t2;
+ b12 += b13 + k3;
+ b13 = ((b13 << 22) | (b13 >> (64 - 22))) ^ b12;
+
+ b15 += k6 + 8;
+ b14 += b15 + k5 + t0;
+ b15 = ((b15 << 37) | (b15 >> (64 - 37))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 38) | (b9 >> (64 - 38))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 19) | (b13 >> (64 - 19))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 10) | (b11 >> (64 - 10))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 55) | (b15 >> (64 - 55))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 49) | (b7 >> (64 - 49))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 18) | (b3 >> (64 - 18))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 23) | (b5 >> (64 - 23))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 52) | (b1 >> (64 - 52))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 33) | (b7 >> (64 - 33))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 4) | (b5 >> (64 - 4))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 51) | (b3 >> (64 - 51))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 34) | (b15 >> (64 - 34))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 41) | (b13 >> (64 - 41))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 59) | (b11 >> (64 - 59))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 17) | (b9 >> (64 - 17))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 5) | (b15 >> (64 - 5))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 20) | (b11 >> (64 - 20))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 48) | (b13 >> (64 - 48))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 41) | (b9 >> (64 - 41))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 47) | (b1 >> (64 - 47))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 28) | (b5 >> (64 - 28))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 25) | (b7 >> (64 - 25))) ^ b12;
+
+ b1 += k10;
+ b0 += b1 + k9;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b0;
+
+ b3 += k12;
+ b2 += b3 + k11;
+ b3 = ((b3 << 9) | (b3 >> (64 - 9))) ^ b2;
+
+ b5 += k14;
+ b4 += b5 + k13;
+ b5 = ((b5 << 37) | (b5 >> (64 - 37))) ^ b4;
+
+ b7 += k16;
+ b6 += b7 + k15;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b6;
+
+ b9 += k1;
+ b8 += b9 + k0;
+ b9 = ((b9 << 12) | (b9 >> (64 - 12))) ^ b8;
+
+ b11 += k3;
+ b10 += b11 + k2;
+ b11 = ((b11 << 47) | (b11 >> (64 - 47))) ^ b10;
+
+ b13 += k5 + t0;
+ b12 += b13 + k4;
+ b13 = ((b13 << 44) | (b13 >> (64 - 44))) ^ b12;
+
+ b15 += k7 + 9;
+ b14 += b15 + k6 + t1;
+ b15 = ((b15 << 30) | (b15 >> (64 - 30))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 16) | (b9 >> (64 - 16))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 34) | (b13 >> (64 - 34))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 56) | (b11 >> (64 - 56))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 51) | (b15 >> (64 - 51))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 4) | (b7 >> (64 - 4))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 53) | (b3 >> (64 - 53))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 42) | (b5 >> (64 - 42))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 44) | (b5 >> (64 - 44))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 47) | (b3 >> (64 - 47))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 19) | (b15 >> (64 - 19))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 42) | (b13 >> (64 - 42))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 44) | (b11 >> (64 - 44))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 25) | (b9 >> (64 - 25))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 9) | (b15 >> (64 - 9))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 48) | (b11 >> (64 - 48))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 35) | (b13 >> (64 - 35))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 52) | (b9 >> (64 - 52))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 31) | (b5 >> (64 - 31))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 37) | (b3 >> (64 - 37))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 20) | (b7 >> (64 - 20))) ^ b12;
+
+ b1 += k11;
+ b0 += b1 + k10;
+ b1 = ((b1 << 24) | (b1 >> (64 - 24))) ^ b0;
+
+ b3 += k13;
+ b2 += b3 + k12;
+ b3 = ((b3 << 13) | (b3 >> (64 - 13))) ^ b2;
+
+ b5 += k15;
+ b4 += b5 + k14;
+ b5 = ((b5 << 8) | (b5 >> (64 - 8))) ^ b4;
+
+ b7 += k0;
+ b6 += b7 + k16;
+ b7 = ((b7 << 47) | (b7 >> (64 - 47))) ^ b6;
+
+ b9 += k2;
+ b8 += b9 + k1;
+ b9 = ((b9 << 8) | (b9 >> (64 - 8))) ^ b8;
+
+ b11 += k4;
+ b10 += b11 + k3;
+ b11 = ((b11 << 17) | (b11 >> (64 - 17))) ^ b10;
+
+ b13 += k6 + t1;
+ b12 += b13 + k5;
+ b13 = ((b13 << 22) | (b13 >> (64 - 22))) ^ b12;
+
+ b15 += k8 + 10;
+ b14 += b15 + k7 + t2;
+ b15 = ((b15 << 37) | (b15 >> (64 - 37))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 38) | (b9 >> (64 - 38))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 19) | (b13 >> (64 - 19))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 10) | (b11 >> (64 - 10))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 55) | (b15 >> (64 - 55))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 49) | (b7 >> (64 - 49))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 18) | (b3 >> (64 - 18))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 23) | (b5 >> (64 - 23))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 52) | (b1 >> (64 - 52))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 33) | (b7 >> (64 - 33))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 4) | (b5 >> (64 - 4))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 51) | (b3 >> (64 - 51))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 34) | (b15 >> (64 - 34))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 41) | (b13 >> (64 - 41))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 59) | (b11 >> (64 - 59))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 17) | (b9 >> (64 - 17))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 5) | (b15 >> (64 - 5))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 20) | (b11 >> (64 - 20))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 48) | (b13 >> (64 - 48))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 41) | (b9 >> (64 - 41))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 47) | (b1 >> (64 - 47))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 28) | (b5 >> (64 - 28))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 25) | (b7 >> (64 - 25))) ^ b12;
+
+ b1 += k12;
+ b0 += b1 + k11;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b0;
+
+ b3 += k14;
+ b2 += b3 + k13;
+ b3 = ((b3 << 9) | (b3 >> (64 - 9))) ^ b2;
+
+ b5 += k16;
+ b4 += b5 + k15;
+ b5 = ((b5 << 37) | (b5 >> (64 - 37))) ^ b4;
+
+ b7 += k1;
+ b6 += b7 + k0;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b6;
+
+ b9 += k3;
+ b8 += b9 + k2;
+ b9 = ((b9 << 12) | (b9 >> (64 - 12))) ^ b8;
+
+ b11 += k5;
+ b10 += b11 + k4;
+ b11 = ((b11 << 47) | (b11 >> (64 - 47))) ^ b10;
+
+ b13 += k7 + t2;
+ b12 += b13 + k6;
+ b13 = ((b13 << 44) | (b13 >> (64 - 44))) ^ b12;
+
+ b15 += k9 + 11;
+ b14 += b15 + k8 + t0;
+ b15 = ((b15 << 30) | (b15 >> (64 - 30))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 16) | (b9 >> (64 - 16))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 34) | (b13 >> (64 - 34))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 56) | (b11 >> (64 - 56))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 51) | (b15 >> (64 - 51))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 4) | (b7 >> (64 - 4))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 53) | (b3 >> (64 - 53))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 42) | (b5 >> (64 - 42))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 44) | (b5 >> (64 - 44))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 47) | (b3 >> (64 - 47))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 19) | (b15 >> (64 - 19))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 42) | (b13 >> (64 - 42))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 44) | (b11 >> (64 - 44))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 25) | (b9 >> (64 - 25))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 9) | (b15 >> (64 - 9))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 48) | (b11 >> (64 - 48))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 35) | (b13 >> (64 - 35))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 52) | (b9 >> (64 - 52))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 31) | (b5 >> (64 - 31))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 37) | (b3 >> (64 - 37))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 20) | (b7 >> (64 - 20))) ^ b12;
+
+ b1 += k13;
+ b0 += b1 + k12;
+ b1 = ((b1 << 24) | (b1 >> (64 - 24))) ^ b0;
+
+ b3 += k15;
+ b2 += b3 + k14;
+ b3 = ((b3 << 13) | (b3 >> (64 - 13))) ^ b2;
+
+ b5 += k0;
+ b4 += b5 + k16;
+ b5 = ((b5 << 8) | (b5 >> (64 - 8))) ^ b4;
+
+ b7 += k2;
+ b6 += b7 + k1;
+ b7 = ((b7 << 47) | (b7 >> (64 - 47))) ^ b6;
+
+ b9 += k4;
+ b8 += b9 + k3;
+ b9 = ((b9 << 8) | (b9 >> (64 - 8))) ^ b8;
+
+ b11 += k6;
+ b10 += b11 + k5;
+ b11 = ((b11 << 17) | (b11 >> (64 - 17))) ^ b10;
+
+ b13 += k8 + t0;
+ b12 += b13 + k7;
+ b13 = ((b13 << 22) | (b13 >> (64 - 22))) ^ b12;
+
+ b15 += k10 + 12;
+ b14 += b15 + k9 + t1;
+ b15 = ((b15 << 37) | (b15 >> (64 - 37))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 38) | (b9 >> (64 - 38))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 19) | (b13 >> (64 - 19))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 10) | (b11 >> (64 - 10))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 55) | (b15 >> (64 - 55))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 49) | (b7 >> (64 - 49))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 18) | (b3 >> (64 - 18))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 23) | (b5 >> (64 - 23))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 52) | (b1 >> (64 - 52))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 33) | (b7 >> (64 - 33))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 4) | (b5 >> (64 - 4))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 51) | (b3 >> (64 - 51))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 34) | (b15 >> (64 - 34))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 41) | (b13 >> (64 - 41))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 59) | (b11 >> (64 - 59))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 17) | (b9 >> (64 - 17))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 5) | (b15 >> (64 - 5))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 20) | (b11 >> (64 - 20))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 48) | (b13 >> (64 - 48))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 41) | (b9 >> (64 - 41))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 47) | (b1 >> (64 - 47))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 28) | (b5 >> (64 - 28))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 25) | (b7 >> (64 - 25))) ^ b12;
+
+ b1 += k14;
+ b0 += b1 + k13;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b0;
+
+ b3 += k16;
+ b2 += b3 + k15;
+ b3 = ((b3 << 9) | (b3 >> (64 - 9))) ^ b2;
+
+ b5 += k1;
+ b4 += b5 + k0;
+ b5 = ((b5 << 37) | (b5 >> (64 - 37))) ^ b4;
+
+ b7 += k3;
+ b6 += b7 + k2;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b6;
+
+ b9 += k5;
+ b8 += b9 + k4;
+ b9 = ((b9 << 12) | (b9 >> (64 - 12))) ^ b8;
+
+ b11 += k7;
+ b10 += b11 + k6;
+ b11 = ((b11 << 47) | (b11 >> (64 - 47))) ^ b10;
+
+ b13 += k9 + t1;
+ b12 += b13 + k8;
+ b13 = ((b13 << 44) | (b13 >> (64 - 44))) ^ b12;
+
+ b15 += k11 + 13;
+ b14 += b15 + k10 + t2;
+ b15 = ((b15 << 30) | (b15 >> (64 - 30))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 16) | (b9 >> (64 - 16))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 34) | (b13 >> (64 - 34))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 56) | (b11 >> (64 - 56))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 51) | (b15 >> (64 - 51))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 4) | (b7 >> (64 - 4))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 53) | (b3 >> (64 - 53))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 42) | (b5 >> (64 - 42))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 44) | (b5 >> (64 - 44))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 47) | (b3 >> (64 - 47))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 19) | (b15 >> (64 - 19))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 42) | (b13 >> (64 - 42))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 44) | (b11 >> (64 - 44))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 25) | (b9 >> (64 - 25))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 9) | (b15 >> (64 - 9))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 48) | (b11 >> (64 - 48))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 35) | (b13 >> (64 - 35))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 52) | (b9 >> (64 - 52))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 31) | (b5 >> (64 - 31))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 37) | (b3 >> (64 - 37))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 20) | (b7 >> (64 - 20))) ^ b12;
+
+ b1 += k15;
+ b0 += b1 + k14;
+ b1 = ((b1 << 24) | (b1 >> (64 - 24))) ^ b0;
+
+ b3 += k0;
+ b2 += b3 + k16;
+ b3 = ((b3 << 13) | (b3 >> (64 - 13))) ^ b2;
+
+ b5 += k2;
+ b4 += b5 + k1;
+ b5 = ((b5 << 8) | (b5 >> (64 - 8))) ^ b4;
+
+ b7 += k4;
+ b6 += b7 + k3;
+ b7 = ((b7 << 47) | (b7 >> (64 - 47))) ^ b6;
+
+ b9 += k6;
+ b8 += b9 + k5;
+ b9 = ((b9 << 8) | (b9 >> (64 - 8))) ^ b8;
+
+ b11 += k8;
+ b10 += b11 + k7;
+ b11 = ((b11 << 17) | (b11 >> (64 - 17))) ^ b10;
+
+ b13 += k10 + t2;
+ b12 += b13 + k9;
+ b13 = ((b13 << 22) | (b13 >> (64 - 22))) ^ b12;
+
+ b15 += k12 + 14;
+ b14 += b15 + k11 + t0;
+ b15 = ((b15 << 37) | (b15 >> (64 - 37))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 38) | (b9 >> (64 - 38))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 19) | (b13 >> (64 - 19))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 10) | (b11 >> (64 - 10))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 55) | (b15 >> (64 - 55))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 49) | (b7 >> (64 - 49))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 18) | (b3 >> (64 - 18))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 23) | (b5 >> (64 - 23))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 52) | (b1 >> (64 - 52))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 33) | (b7 >> (64 - 33))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 4) | (b5 >> (64 - 4))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 51) | (b3 >> (64 - 51))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 34) | (b15 >> (64 - 34))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 41) | (b13 >> (64 - 41))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 59) | (b11 >> (64 - 59))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 17) | (b9 >> (64 - 17))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 5) | (b15 >> (64 - 5))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 20) | (b11 >> (64 - 20))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 48) | (b13 >> (64 - 48))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 41) | (b9 >> (64 - 41))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 47) | (b1 >> (64 - 47))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 28) | (b5 >> (64 - 28))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 25) | (b7 >> (64 - 25))) ^ b12;
+
+ b1 += k16;
+ b0 += b1 + k15;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b0;
+
+ b3 += k1;
+ b2 += b3 + k0;
+ b3 = ((b3 << 9) | (b3 >> (64 - 9))) ^ b2;
+
+ b5 += k3;
+ b4 += b5 + k2;
+ b5 = ((b5 << 37) | (b5 >> (64 - 37))) ^ b4;
+
+ b7 += k5;
+ b6 += b7 + k4;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b6;
+
+ b9 += k7;
+ b8 += b9 + k6;
+ b9 = ((b9 << 12) | (b9 >> (64 - 12))) ^ b8;
+
+ b11 += k9;
+ b10 += b11 + k8;
+ b11 = ((b11 << 47) | (b11 >> (64 - 47))) ^ b10;
+
+ b13 += k11 + t0;
+ b12 += b13 + k10;
+ b13 = ((b13 << 44) | (b13 >> (64 - 44))) ^ b12;
+
+ b15 += k13 + 15;
+ b14 += b15 + k12 + t1;
+ b15 = ((b15 << 30) | (b15 >> (64 - 30))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 16) | (b9 >> (64 - 16))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 34) | (b13 >> (64 - 34))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 56) | (b11 >> (64 - 56))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 51) | (b15 >> (64 - 51))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 4) | (b7 >> (64 - 4))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 53) | (b3 >> (64 - 53))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 42) | (b5 >> (64 - 42))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 44) | (b5 >> (64 - 44))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 47) | (b3 >> (64 - 47))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 19) | (b15 >> (64 - 19))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 42) | (b13 >> (64 - 42))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 44) | (b11 >> (64 - 44))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 25) | (b9 >> (64 - 25))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 9) | (b15 >> (64 - 9))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 48) | (b11 >> (64 - 48))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 35) | (b13 >> (64 - 35))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 52) | (b9 >> (64 - 52))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 31) | (b5 >> (64 - 31))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 37) | (b3 >> (64 - 37))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 20) | (b7 >> (64 - 20))) ^ b12;
+
+ b1 += k0;
+ b0 += b1 + k16;
+ b1 = ((b1 << 24) | (b1 >> (64 - 24))) ^ b0;
+
+ b3 += k2;
+ b2 += b3 + k1;
+ b3 = ((b3 << 13) | (b3 >> (64 - 13))) ^ b2;
+
+ b5 += k4;
+ b4 += b5 + k3;
+ b5 = ((b5 << 8) | (b5 >> (64 - 8))) ^ b4;
+
+ b7 += k6;
+ b6 += b7 + k5;
+ b7 = ((b7 << 47) | (b7 >> (64 - 47))) ^ b6;
+
+ b9 += k8;
+ b8 += b9 + k7;
+ b9 = ((b9 << 8) | (b9 >> (64 - 8))) ^ b8;
+
+ b11 += k10;
+ b10 += b11 + k9;
+ b11 = ((b11 << 17) | (b11 >> (64 - 17))) ^ b10;
+
+ b13 += k12 + t1;
+ b12 += b13 + k11;
+ b13 = ((b13 << 22) | (b13 >> (64 - 22))) ^ b12;
+
+ b15 += k14 + 16;
+ b14 += b15 + k13 + t2;
+ b15 = ((b15 << 37) | (b15 >> (64 - 37))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 38) | (b9 >> (64 - 38))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 19) | (b13 >> (64 - 19))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 10) | (b11 >> (64 - 10))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 55) | (b15 >> (64 - 55))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 49) | (b7 >> (64 - 49))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 18) | (b3 >> (64 - 18))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 23) | (b5 >> (64 - 23))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 52) | (b1 >> (64 - 52))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 33) | (b7 >> (64 - 33))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 4) | (b5 >> (64 - 4))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 51) | (b3 >> (64 - 51))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 34) | (b15 >> (64 - 34))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 41) | (b13 >> (64 - 41))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 59) | (b11 >> (64 - 59))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 17) | (b9 >> (64 - 17))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 5) | (b15 >> (64 - 5))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 20) | (b11 >> (64 - 20))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 48) | (b13 >> (64 - 48))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 41) | (b9 >> (64 - 41))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 47) | (b1 >> (64 - 47))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 28) | (b5 >> (64 - 28))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 25) | (b7 >> (64 - 25))) ^ b12;
+
+ b1 += k1;
+ b0 += b1 + k0;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b0;
+
+ b3 += k3;
+ b2 += b3 + k2;
+ b3 = ((b3 << 9) | (b3 >> (64 - 9))) ^ b2;
+
+ b5 += k5;
+ b4 += b5 + k4;
+ b5 = ((b5 << 37) | (b5 >> (64 - 37))) ^ b4;
+
+ b7 += k7;
+ b6 += b7 + k6;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b6;
+
+ b9 += k9;
+ b8 += b9 + k8;
+ b9 = ((b9 << 12) | (b9 >> (64 - 12))) ^ b8;
+
+ b11 += k11;
+ b10 += b11 + k10;
+ b11 = ((b11 << 47) | (b11 >> (64 - 47))) ^ b10;
+
+ b13 += k13 + t2;
+ b12 += b13 + k12;
+ b13 = ((b13 << 44) | (b13 >> (64 - 44))) ^ b12;
+
+ b15 += k15 + 17;
+ b14 += b15 + k14 + t0;
+ b15 = ((b15 << 30) | (b15 >> (64 - 30))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 16) | (b9 >> (64 - 16))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 34) | (b13 >> (64 - 34))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 56) | (b11 >> (64 - 56))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 51) | (b15 >> (64 - 51))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 4) | (b7 >> (64 - 4))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 53) | (b3 >> (64 - 53))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 42) | (b5 >> (64 - 42))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 44) | (b5 >> (64 - 44))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 47) | (b3 >> (64 - 47))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 19) | (b15 >> (64 - 19))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 42) | (b13 >> (64 - 42))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 44) | (b11 >> (64 - 44))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 25) | (b9 >> (64 - 25))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 9) | (b15 >> (64 - 9))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 48) | (b11 >> (64 - 48))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 35) | (b13 >> (64 - 35))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 52) | (b9 >> (64 - 52))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 31) | (b5 >> (64 - 31))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 37) | (b3 >> (64 - 37))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 20) | (b7 >> (64 - 20))) ^ b12;
+
+ b1 += k2;
+ b0 += b1 + k1;
+ b1 = ((b1 << 24) | (b1 >> (64 - 24))) ^ b0;
+
+ b3 += k4;
+ b2 += b3 + k3;
+ b3 = ((b3 << 13) | (b3 >> (64 - 13))) ^ b2;
+
+ b5 += k6;
+ b4 += b5 + k5;
+ b5 = ((b5 << 8) | (b5 >> (64 - 8))) ^ b4;
+
+ b7 += k8;
+ b6 += b7 + k7;
+ b7 = ((b7 << 47) | (b7 >> (64 - 47))) ^ b6;
+
+ b9 += k10;
+ b8 += b9 + k9;
+ b9 = ((b9 << 8) | (b9 >> (64 - 8))) ^ b8;
+
+ b11 += k12;
+ b10 += b11 + k11;
+ b11 = ((b11 << 17) | (b11 >> (64 - 17))) ^ b10;
+
+ b13 += k14 + t0;
+ b12 += b13 + k13;
+ b13 = ((b13 << 22) | (b13 >> (64 - 22))) ^ b12;
+
+ b15 += k16 + 18;
+ b14 += b15 + k15 + t1;
+ b15 = ((b15 << 37) | (b15 >> (64 - 37))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 38) | (b9 >> (64 - 38))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 19) | (b13 >> (64 - 19))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 10) | (b11 >> (64 - 10))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 55) | (b15 >> (64 - 55))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 49) | (b7 >> (64 - 49))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 18) | (b3 >> (64 - 18))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 23) | (b5 >> (64 - 23))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 52) | (b1 >> (64 - 52))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 33) | (b7 >> (64 - 33))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 4) | (b5 >> (64 - 4))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 51) | (b3 >> (64 - 51))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 34) | (b15 >> (64 - 34))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 41) | (b13 >> (64 - 41))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 59) | (b11 >> (64 - 59))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 17) | (b9 >> (64 - 17))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 5) | (b15 >> (64 - 5))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 20) | (b11 >> (64 - 20))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 48) | (b13 >> (64 - 48))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 41) | (b9 >> (64 - 41))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 47) | (b1 >> (64 - 47))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 28) | (b5 >> (64 - 28))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 25) | (b7 >> (64 - 25))) ^ b12;
+
+ b1 += k3;
+ b0 += b1 + k2;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b0;
+
+ b3 += k5;
+ b2 += b3 + k4;
+ b3 = ((b3 << 9) | (b3 >> (64 - 9))) ^ b2;
+
+ b5 += k7;
+ b4 += b5 + k6;
+ b5 = ((b5 << 37) | (b5 >> (64 - 37))) ^ b4;
+
+ b7 += k9;
+ b6 += b7 + k8;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b6;
+
+ b9 += k11;
+ b8 += b9 + k10;
+ b9 = ((b9 << 12) | (b9 >> (64 - 12))) ^ b8;
+
+ b11 += k13;
+ b10 += b11 + k12;
+ b11 = ((b11 << 47) | (b11 >> (64 - 47))) ^ b10;
+
+ b13 += k15 + t1;
+ b12 += b13 + k14;
+ b13 = ((b13 << 44) | (b13 >> (64 - 44))) ^ b12;
+
+ b15 += k0 + 19;
+ b14 += b15 + k16 + t2;
+ b15 = ((b15 << 30) | (b15 >> (64 - 30))) ^ b14;
+
+ b0 += b9;
+ b9 = ((b9 << 16) | (b9 >> (64 - 16))) ^ b0;
+
+ b2 += b13;
+ b13 = ((b13 << 34) | (b13 >> (64 - 34))) ^ b2;
+
+ b6 += b11;
+ b11 = ((b11 << 56) | (b11 >> (64 - 56))) ^ b6;
+
+ b4 += b15;
+ b15 = ((b15 << 51) | (b15 >> (64 - 51))) ^ b4;
+
+ b10 += b7;
+ b7 = ((b7 << 4) | (b7 >> (64 - 4))) ^ b10;
+
+ b12 += b3;
+ b3 = ((b3 << 53) | (b3 >> (64 - 53))) ^ b12;
+
+ b14 += b5;
+ b5 = ((b5 << 42) | (b5 >> (64 - 42))) ^ b14;
+
+ b8 += b1;
+ b1 = ((b1 << 41) | (b1 >> (64 - 41))) ^ b8;
+
+ b0 += b7;
+ b7 = ((b7 << 31) | (b7 >> (64 - 31))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 44) | (b5 >> (64 - 44))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 47) | (b3 >> (64 - 47))) ^ b4;
+
+ b6 += b1;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b6;
+
+ b12 += b15;
+ b15 = ((b15 << 19) | (b15 >> (64 - 19))) ^ b12;
+
+ b14 += b13;
+ b13 = ((b13 << 42) | (b13 >> (64 - 42))) ^ b14;
+
+ b8 += b11;
+ b11 = ((b11 << 44) | (b11 >> (64 - 44))) ^ b8;
+
+ b10 += b9;
+ b9 = ((b9 << 25) | (b9 >> (64 - 25))) ^ b10;
+
+ b0 += b15;
+ b15 = ((b15 << 9) | (b15 >> (64 - 9))) ^ b0;
+
+ b2 += b11;
+ b11 = ((b11 << 48) | (b11 >> (64 - 48))) ^ b2;
+
+ b6 += b13;
+ b13 = ((b13 << 35) | (b13 >> (64 - 35))) ^ b6;
+
+ b4 += b9;
+ b9 = ((b9 << 52) | (b9 >> (64 - 52))) ^ b4;
+
+ b14 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b14;
+
+ b8 += b5;
+ b5 = ((b5 << 31) | (b5 >> (64 - 31))) ^ b8;
+
+ b10 += b3;
+ b3 = ((b3 << 37) | (b3 >> (64 - 37))) ^ b10;
+
+ b12 += b7;
+ b7 = ((b7 << 20) | (b7 >> (64 - 20))) ^ b12;
+
+ output[0] = b0 + k3;
+ output[1] = b1 + k4;
+ output[2] = b2 + k5;
+ output[3] = b3 + k6;
+ output[4] = b4 + k7;
+ output[5] = b5 + k8;
+ output[6] = b6 + k9;
+ output[7] = b7 + k10;
+ output[8] = b8 + k11;
+ output[9] = b9 + k12;
+ output[10] = b10 + k13;
+ output[11] = b11 + k14;
+ output[12] = b12 + k15;
+ output[13] = b13 + k16 + t2;
+ output[14] = b14 + k0 + t0;
+ output[15] = b15 + k1 + 20;
+}
+
+void threefishDecrypt1024(struct threefish_key *keyCtx, u64 *input, u64 *output)
+{
+ u64 b0 = input[0], b1 = input[1],
+ b2 = input[2], b3 = input[3],
+ b4 = input[4], b5 = input[5],
+ b6 = input[6], b7 = input[7],
+ b8 = input[8], b9 = input[9],
+ b10 = input[10], b11 = input[11],
+ b12 = input[12], b13 = input[13],
+ b14 = input[14], b15 = input[15];
+ u64 k0 = keyCtx->key[0], k1 = keyCtx->key[1],
+ k2 = keyCtx->key[2], k3 = keyCtx->key[3],
+ k4 = keyCtx->key[4], k5 = keyCtx->key[5],
+ k6 = keyCtx->key[6], k7 = keyCtx->key[7],
+ k8 = keyCtx->key[8], k9 = keyCtx->key[9],
+ k10 = keyCtx->key[10], k11 = keyCtx->key[11],
+ k12 = keyCtx->key[12], k13 = keyCtx->key[13],
+ k14 = keyCtx->key[14], k15 = keyCtx->key[15],
+ k16 = keyCtx->key[16];
+ u64 t0 = keyCtx->tweak[0], t1 = keyCtx->tweak[1],
+ t2 = keyCtx->tweak[2];
+ u64 tmp;
+
+ b0 -= k3;
+ b1 -= k4;
+ b2 -= k5;
+ b3 -= k6;
+ b4 -= k7;
+ b5 -= k8;
+ b6 -= k9;
+ b7 -= k10;
+ b8 -= k11;
+ b9 -= k12;
+ b10 -= k13;
+ b11 -= k14;
+ b12 -= k15;
+ b13 -= k16 + t2;
+ b14 -= k0 + t0;
+ b15 -= k1 + 20;
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 20) | (tmp << (64 - 20));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 37) | (tmp << (64 - 37));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 31) | (tmp << (64 - 31));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 52) | (tmp << (64 - 52));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 35) | (tmp << (64 - 35));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 48) | (tmp << (64 - 48));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 25) | (tmp << (64 - 25));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 44) | (tmp << (64 - 44));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 19) | (tmp << (64 - 19));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 47) | (tmp << (64 - 47));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 44) | (tmp << (64 - 44));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 53) | (tmp << (64 - 53));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 4) | (tmp << (64 - 4));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 56) | (tmp << (64 - 56));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 34) | (tmp << (64 - 34));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 16) | (tmp << (64 - 16));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 30) | (tmp << (64 - 30));
+ b14 -= b15 + k16 + t2;
+ b15 -= k0 + 19;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 44) | (tmp << (64 - 44));
+ b12 -= b13 + k14;
+ b13 -= k15 + t1;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 47) | (tmp << (64 - 47));
+ b10 -= b11 + k12;
+ b11 -= k13;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 12) | (tmp << (64 - 12));
+ b8 -= b9 + k10;
+ b9 -= k11;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b6 -= b7 + k8;
+ b7 -= k9;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 37) | (tmp << (64 - 37));
+ b4 -= b5 + k6;
+ b5 -= k7;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 9) | (tmp << (64 - 9));
+ b2 -= b3 + k4;
+ b3 -= k5;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b0 -= b1 + k2;
+ b1 -= k3;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 25) | (tmp << (64 - 25));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 28) | (tmp << (64 - 28));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 47) | (tmp << (64 - 47));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 41) | (tmp << (64 - 41));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 48) | (tmp << (64 - 48));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 20) | (tmp << (64 - 20));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 59) | (tmp << (64 - 59));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 41) | (tmp << (64 - 41));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 34) | (tmp << (64 - 34));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 4) | (tmp << (64 - 4));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 33) | (tmp << (64 - 33));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 52) | (tmp << (64 - 52));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 18) | (tmp << (64 - 18));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 49) | (tmp << (64 - 49));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 55) | (tmp << (64 - 55));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 19) | (tmp << (64 - 19));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 38) | (tmp << (64 - 38));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 37) | (tmp << (64 - 37));
+ b14 -= b15 + k15 + t1;
+ b15 -= k16 + 18;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 22) | (tmp << (64 - 22));
+ b12 -= b13 + k13;
+ b13 -= k14 + t0;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b11 + k11;
+ b11 -= k12;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 8) | (tmp << (64 - 8));
+ b8 -= b9 + k9;
+ b9 -= k10;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 47) | (tmp << (64 - 47));
+ b6 -= b7 + k7;
+ b7 -= k8;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 8) | (tmp << (64 - 8));
+ b4 -= b5 + k5;
+ b5 -= k6;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b3 + k3;
+ b3 -= k4;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 24) | (tmp << (64 - 24));
+ b0 -= b1 + k1;
+ b1 -= k2;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 20) | (tmp << (64 - 20));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 37) | (tmp << (64 - 37));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 31) | (tmp << (64 - 31));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 52) | (tmp << (64 - 52));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 35) | (tmp << (64 - 35));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 48) | (tmp << (64 - 48));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 25) | (tmp << (64 - 25));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 44) | (tmp << (64 - 44));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 19) | (tmp << (64 - 19));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 47) | (tmp << (64 - 47));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 44) | (tmp << (64 - 44));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 53) | (tmp << (64 - 53));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 4) | (tmp << (64 - 4));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 56) | (tmp << (64 - 56));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 34) | (tmp << (64 - 34));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 16) | (tmp << (64 - 16));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 30) | (tmp << (64 - 30));
+ b14 -= b15 + k14 + t0;
+ b15 -= k15 + 17;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 44) | (tmp << (64 - 44));
+ b12 -= b13 + k12;
+ b13 -= k13 + t2;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 47) | (tmp << (64 - 47));
+ b10 -= b11 + k10;
+ b11 -= k11;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 12) | (tmp << (64 - 12));
+ b8 -= b9 + k8;
+ b9 -= k9;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b6 -= b7 + k6;
+ b7 -= k7;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 37) | (tmp << (64 - 37));
+ b4 -= b5 + k4;
+ b5 -= k5;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 9) | (tmp << (64 - 9));
+ b2 -= b3 + k2;
+ b3 -= k3;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b0 -= b1 + k0;
+ b1 -= k1;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 25) | (tmp << (64 - 25));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 28) | (tmp << (64 - 28));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 47) | (tmp << (64 - 47));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 41) | (tmp << (64 - 41));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 48) | (tmp << (64 - 48));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 20) | (tmp << (64 - 20));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 59) | (tmp << (64 - 59));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 41) | (tmp << (64 - 41));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 34) | (tmp << (64 - 34));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 4) | (tmp << (64 - 4));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 33) | (tmp << (64 - 33));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 52) | (tmp << (64 - 52));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 18) | (tmp << (64 - 18));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 49) | (tmp << (64 - 49));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 55) | (tmp << (64 - 55));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 19) | (tmp << (64 - 19));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 38) | (tmp << (64 - 38));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 37) | (tmp << (64 - 37));
+ b14 -= b15 + k13 + t2;
+ b15 -= k14 + 16;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 22) | (tmp << (64 - 22));
+ b12 -= b13 + k11;
+ b13 -= k12 + t1;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b11 + k9;
+ b11 -= k10;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 8) | (tmp << (64 - 8));
+ b8 -= b9 + k7;
+ b9 -= k8;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 47) | (tmp << (64 - 47));
+ b6 -= b7 + k5;
+ b7 -= k6;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 8) | (tmp << (64 - 8));
+ b4 -= b5 + k3;
+ b5 -= k4;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b3 + k1;
+ b3 -= k2;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 24) | (tmp << (64 - 24));
+ b0 -= b1 + k16;
+ b1 -= k0;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 20) | (tmp << (64 - 20));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 37) | (tmp << (64 - 37));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 31) | (tmp << (64 - 31));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 52) | (tmp << (64 - 52));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 35) | (tmp << (64 - 35));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 48) | (tmp << (64 - 48));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 25) | (tmp << (64 - 25));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 44) | (tmp << (64 - 44));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 19) | (tmp << (64 - 19));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 47) | (tmp << (64 - 47));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 44) | (tmp << (64 - 44));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 53) | (tmp << (64 - 53));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 4) | (tmp << (64 - 4));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 56) | (tmp << (64 - 56));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 34) | (tmp << (64 - 34));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 16) | (tmp << (64 - 16));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 30) | (tmp << (64 - 30));
+ b14 -= b15 + k12 + t1;
+ b15 -= k13 + 15;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 44) | (tmp << (64 - 44));
+ b12 -= b13 + k10;
+ b13 -= k11 + t0;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 47) | (tmp << (64 - 47));
+ b10 -= b11 + k8;
+ b11 -= k9;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 12) | (tmp << (64 - 12));
+ b8 -= b9 + k6;
+ b9 -= k7;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b6 -= b7 + k4;
+ b7 -= k5;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 37) | (tmp << (64 - 37));
+ b4 -= b5 + k2;
+ b5 -= k3;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 9) | (tmp << (64 - 9));
+ b2 -= b3 + k0;
+ b3 -= k1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b0 -= b1 + k15;
+ b1 -= k16;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 25) | (tmp << (64 - 25));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 28) | (tmp << (64 - 28));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 47) | (tmp << (64 - 47));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 41) | (tmp << (64 - 41));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 48) | (tmp << (64 - 48));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 20) | (tmp << (64 - 20));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 59) | (tmp << (64 - 59));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 41) | (tmp << (64 - 41));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 34) | (tmp << (64 - 34));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 4) | (tmp << (64 - 4));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 33) | (tmp << (64 - 33));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 52) | (tmp << (64 - 52));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 18) | (tmp << (64 - 18));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 49) | (tmp << (64 - 49));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 55) | (tmp << (64 - 55));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 19) | (tmp << (64 - 19));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 38) | (tmp << (64 - 38));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 37) | (tmp << (64 - 37));
+ b14 -= b15 + k11 + t0;
+ b15 -= k12 + 14;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 22) | (tmp << (64 - 22));
+ b12 -= b13 + k9;
+ b13 -= k10 + t2;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b11 + k7;
+ b11 -= k8;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 8) | (tmp << (64 - 8));
+ b8 -= b9 + k5;
+ b9 -= k6;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 47) | (tmp << (64 - 47));
+ b6 -= b7 + k3;
+ b7 -= k4;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 8) | (tmp << (64 - 8));
+ b4 -= b5 + k1;
+ b5 -= k2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b3 + k16;
+ b3 -= k0;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 24) | (tmp << (64 - 24));
+ b0 -= b1 + k14;
+ b1 -= k15;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 20) | (tmp << (64 - 20));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 37) | (tmp << (64 - 37));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 31) | (tmp << (64 - 31));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 52) | (tmp << (64 - 52));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 35) | (tmp << (64 - 35));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 48) | (tmp << (64 - 48));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 25) | (tmp << (64 - 25));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 44) | (tmp << (64 - 44));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 19) | (tmp << (64 - 19));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 47) | (tmp << (64 - 47));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 44) | (tmp << (64 - 44));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 53) | (tmp << (64 - 53));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 4) | (tmp << (64 - 4));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 56) | (tmp << (64 - 56));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 34) | (tmp << (64 - 34));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 16) | (tmp << (64 - 16));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 30) | (tmp << (64 - 30));
+ b14 -= b15 + k10 + t2;
+ b15 -= k11 + 13;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 44) | (tmp << (64 - 44));
+ b12 -= b13 + k8;
+ b13 -= k9 + t1;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 47) | (tmp << (64 - 47));
+ b10 -= b11 + k6;
+ b11 -= k7;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 12) | (tmp << (64 - 12));
+ b8 -= b9 + k4;
+ b9 -= k5;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b6 -= b7 + k2;
+ b7 -= k3;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 37) | (tmp << (64 - 37));
+ b4 -= b5 + k0;
+ b5 -= k1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 9) | (tmp << (64 - 9));
+ b2 -= b3 + k15;
+ b3 -= k16;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b0 -= b1 + k13;
+ b1 -= k14;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 25) | (tmp << (64 - 25));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 28) | (tmp << (64 - 28));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 47) | (tmp << (64 - 47));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 41) | (tmp << (64 - 41));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 48) | (tmp << (64 - 48));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 20) | (tmp << (64 - 20));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 59) | (tmp << (64 - 59));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 41) | (tmp << (64 - 41));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 34) | (tmp << (64 - 34));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 4) | (tmp << (64 - 4));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 33) | (tmp << (64 - 33));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 52) | (tmp << (64 - 52));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 18) | (tmp << (64 - 18));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 49) | (tmp << (64 - 49));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 55) | (tmp << (64 - 55));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 19) | (tmp << (64 - 19));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 38) | (tmp << (64 - 38));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 37) | (tmp << (64 - 37));
+ b14 -= b15 + k9 + t1;
+ b15 -= k10 + 12;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 22) | (tmp << (64 - 22));
+ b12 -= b13 + k7;
+ b13 -= k8 + t0;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b11 + k5;
+ b11 -= k6;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 8) | (tmp << (64 - 8));
+ b8 -= b9 + k3;
+ b9 -= k4;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 47) | (tmp << (64 - 47));
+ b6 -= b7 + k1;
+ b7 -= k2;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 8) | (tmp << (64 - 8));
+ b4 -= b5 + k16;
+ b5 -= k0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b3 + k14;
+ b3 -= k15;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 24) | (tmp << (64 - 24));
+ b0 -= b1 + k12;
+ b1 -= k13;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 20) | (tmp << (64 - 20));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 37) | (tmp << (64 - 37));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 31) | (tmp << (64 - 31));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 52) | (tmp << (64 - 52));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 35) | (tmp << (64 - 35));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 48) | (tmp << (64 - 48));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 25) | (tmp << (64 - 25));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 44) | (tmp << (64 - 44));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 19) | (tmp << (64 - 19));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 47) | (tmp << (64 - 47));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 44) | (tmp << (64 - 44));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 53) | (tmp << (64 - 53));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 4) | (tmp << (64 - 4));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 56) | (tmp << (64 - 56));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 34) | (tmp << (64 - 34));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 16) | (tmp << (64 - 16));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 30) | (tmp << (64 - 30));
+ b14 -= b15 + k8 + t0;
+ b15 -= k9 + 11;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 44) | (tmp << (64 - 44));
+ b12 -= b13 + k6;
+ b13 -= k7 + t2;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 47) | (tmp << (64 - 47));
+ b10 -= b11 + k4;
+ b11 -= k5;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 12) | (tmp << (64 - 12));
+ b8 -= b9 + k2;
+ b9 -= k3;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b6 -= b7 + k0;
+ b7 -= k1;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 37) | (tmp << (64 - 37));
+ b4 -= b5 + k15;
+ b5 -= k16;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 9) | (tmp << (64 - 9));
+ b2 -= b3 + k13;
+ b3 -= k14;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b0 -= b1 + k11;
+ b1 -= k12;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 25) | (tmp << (64 - 25));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 28) | (tmp << (64 - 28));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 47) | (tmp << (64 - 47));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 41) | (tmp << (64 - 41));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 48) | (tmp << (64 - 48));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 20) | (tmp << (64 - 20));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 59) | (tmp << (64 - 59));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 41) | (tmp << (64 - 41));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 34) | (tmp << (64 - 34));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 4) | (tmp << (64 - 4));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 33) | (tmp << (64 - 33));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 52) | (tmp << (64 - 52));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 18) | (tmp << (64 - 18));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 49) | (tmp << (64 - 49));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 55) | (tmp << (64 - 55));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 19) | (tmp << (64 - 19));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 38) | (tmp << (64 - 38));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 37) | (tmp << (64 - 37));
+ b14 -= b15 + k7 + t2;
+ b15 -= k8 + 10;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 22) | (tmp << (64 - 22));
+ b12 -= b13 + k5;
+ b13 -= k6 + t1;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b11 + k3;
+ b11 -= k4;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 8) | (tmp << (64 - 8));
+ b8 -= b9 + k1;
+ b9 -= k2;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 47) | (tmp << (64 - 47));
+ b6 -= b7 + k16;
+ b7 -= k0;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 8) | (tmp << (64 - 8));
+ b4 -= b5 + k14;
+ b5 -= k15;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b3 + k12;
+ b3 -= k13;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 24) | (tmp << (64 - 24));
+ b0 -= b1 + k10;
+ b1 -= k11;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 20) | (tmp << (64 - 20));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 37) | (tmp << (64 - 37));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 31) | (tmp << (64 - 31));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 52) | (tmp << (64 - 52));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 35) | (tmp << (64 - 35));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 48) | (tmp << (64 - 48));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 25) | (tmp << (64 - 25));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 44) | (tmp << (64 - 44));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 19) | (tmp << (64 - 19));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 47) | (tmp << (64 - 47));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 44) | (tmp << (64 - 44));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 53) | (tmp << (64 - 53));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 4) | (tmp << (64 - 4));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 56) | (tmp << (64 - 56));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 34) | (tmp << (64 - 34));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 16) | (tmp << (64 - 16));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 30) | (tmp << (64 - 30));
+ b14 -= b15 + k6 + t1;
+ b15 -= k7 + 9;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 44) | (tmp << (64 - 44));
+ b12 -= b13 + k4;
+ b13 -= k5 + t0;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 47) | (tmp << (64 - 47));
+ b10 -= b11 + k2;
+ b11 -= k3;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 12) | (tmp << (64 - 12));
+ b8 -= b9 + k0;
+ b9 -= k1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b6 -= b7 + k15;
+ b7 -= k16;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 37) | (tmp << (64 - 37));
+ b4 -= b5 + k13;
+ b5 -= k14;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 9) | (tmp << (64 - 9));
+ b2 -= b3 + k11;
+ b3 -= k12;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b0 -= b1 + k9;
+ b1 -= k10;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 25) | (tmp << (64 - 25));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 28) | (tmp << (64 - 28));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 47) | (tmp << (64 - 47));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 41) | (tmp << (64 - 41));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 48) | (tmp << (64 - 48));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 20) | (tmp << (64 - 20));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 59) | (tmp << (64 - 59));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 41) | (tmp << (64 - 41));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 34) | (tmp << (64 - 34));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 4) | (tmp << (64 - 4));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 33) | (tmp << (64 - 33));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 52) | (tmp << (64 - 52));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 18) | (tmp << (64 - 18));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 49) | (tmp << (64 - 49));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 55) | (tmp << (64 - 55));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 19) | (tmp << (64 - 19));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 38) | (tmp << (64 - 38));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 37) | (tmp << (64 - 37));
+ b14 -= b15 + k5 + t0;
+ b15 -= k6 + 8;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 22) | (tmp << (64 - 22));
+ b12 -= b13 + k3;
+ b13 -= k4 + t2;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b11 + k1;
+ b11 -= k2;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 8) | (tmp << (64 - 8));
+ b8 -= b9 + k16;
+ b9 -= k0;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 47) | (tmp << (64 - 47));
+ b6 -= b7 + k14;
+ b7 -= k15;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 8) | (tmp << (64 - 8));
+ b4 -= b5 + k12;
+ b5 -= k13;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b3 + k10;
+ b3 -= k11;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 24) | (tmp << (64 - 24));
+ b0 -= b1 + k8;
+ b1 -= k9;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 20) | (tmp << (64 - 20));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 37) | (tmp << (64 - 37));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 31) | (tmp << (64 - 31));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 52) | (tmp << (64 - 52));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 35) | (tmp << (64 - 35));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 48) | (tmp << (64 - 48));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 25) | (tmp << (64 - 25));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 44) | (tmp << (64 - 44));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 19) | (tmp << (64 - 19));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 47) | (tmp << (64 - 47));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 44) | (tmp << (64 - 44));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 53) | (tmp << (64 - 53));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 4) | (tmp << (64 - 4));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 56) | (tmp << (64 - 56));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 34) | (tmp << (64 - 34));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 16) | (tmp << (64 - 16));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 30) | (tmp << (64 - 30));
+ b14 -= b15 + k4 + t2;
+ b15 -= k5 + 7;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 44) | (tmp << (64 - 44));
+ b12 -= b13 + k2;
+ b13 -= k3 + t1;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 47) | (tmp << (64 - 47));
+ b10 -= b11 + k0;
+ b11 -= k1;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 12) | (tmp << (64 - 12));
+ b8 -= b9 + k15;
+ b9 -= k16;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b6 -= b7 + k13;
+ b7 -= k14;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 37) | (tmp << (64 - 37));
+ b4 -= b5 + k11;
+ b5 -= k12;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 9) | (tmp << (64 - 9));
+ b2 -= b3 + k9;
+ b3 -= k10;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b0 -= b1 + k7;
+ b1 -= k8;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 25) | (tmp << (64 - 25));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 28) | (tmp << (64 - 28));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 47) | (tmp << (64 - 47));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 41) | (tmp << (64 - 41));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 48) | (tmp << (64 - 48));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 20) | (tmp << (64 - 20));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 59) | (tmp << (64 - 59));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 41) | (tmp << (64 - 41));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 34) | (tmp << (64 - 34));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 4) | (tmp << (64 - 4));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 33) | (tmp << (64 - 33));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 52) | (tmp << (64 - 52));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 18) | (tmp << (64 - 18));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 49) | (tmp << (64 - 49));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 55) | (tmp << (64 - 55));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 19) | (tmp << (64 - 19));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 38) | (tmp << (64 - 38));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 37) | (tmp << (64 - 37));
+ b14 -= b15 + k3 + t1;
+ b15 -= k4 + 6;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 22) | (tmp << (64 - 22));
+ b12 -= b13 + k1;
+ b13 -= k2 + t0;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b11 + k16;
+ b11 -= k0;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 8) | (tmp << (64 - 8));
+ b8 -= b9 + k14;
+ b9 -= k15;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 47) | (tmp << (64 - 47));
+ b6 -= b7 + k12;
+ b7 -= k13;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 8) | (tmp << (64 - 8));
+ b4 -= b5 + k10;
+ b5 -= k11;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b3 + k8;
+ b3 -= k9;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 24) | (tmp << (64 - 24));
+ b0 -= b1 + k6;
+ b1 -= k7;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 20) | (tmp << (64 - 20));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 37) | (tmp << (64 - 37));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 31) | (tmp << (64 - 31));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 52) | (tmp << (64 - 52));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 35) | (tmp << (64 - 35));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 48) | (tmp << (64 - 48));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 25) | (tmp << (64 - 25));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 44) | (tmp << (64 - 44));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 19) | (tmp << (64 - 19));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 47) | (tmp << (64 - 47));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 44) | (tmp << (64 - 44));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 53) | (tmp << (64 - 53));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 4) | (tmp << (64 - 4));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 56) | (tmp << (64 - 56));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 34) | (tmp << (64 - 34));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 16) | (tmp << (64 - 16));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 30) | (tmp << (64 - 30));
+ b14 -= b15 + k2 + t0;
+ b15 -= k3 + 5;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 44) | (tmp << (64 - 44));
+ b12 -= b13 + k0;
+ b13 -= k1 + t2;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 47) | (tmp << (64 - 47));
+ b10 -= b11 + k15;
+ b11 -= k16;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 12) | (tmp << (64 - 12));
+ b8 -= b9 + k13;
+ b9 -= k14;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b6 -= b7 + k11;
+ b7 -= k12;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 37) | (tmp << (64 - 37));
+ b4 -= b5 + k9;
+ b5 -= k10;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 9) | (tmp << (64 - 9));
+ b2 -= b3 + k7;
+ b3 -= k8;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b0 -= b1 + k5;
+ b1 -= k6;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 25) | (tmp << (64 - 25));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 28) | (tmp << (64 - 28));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 47) | (tmp << (64 - 47));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 41) | (tmp << (64 - 41));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 48) | (tmp << (64 - 48));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 20) | (tmp << (64 - 20));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 59) | (tmp << (64 - 59));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 41) | (tmp << (64 - 41));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 34) | (tmp << (64 - 34));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 4) | (tmp << (64 - 4));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 33) | (tmp << (64 - 33));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 52) | (tmp << (64 - 52));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 18) | (tmp << (64 - 18));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 49) | (tmp << (64 - 49));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 55) | (tmp << (64 - 55));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 19) | (tmp << (64 - 19));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 38) | (tmp << (64 - 38));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 37) | (tmp << (64 - 37));
+ b14 -= b15 + k1 + t2;
+ b15 -= k2 + 4;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 22) | (tmp << (64 - 22));
+ b12 -= b13 + k16;
+ b13 -= k0 + t1;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b11 + k14;
+ b11 -= k15;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 8) | (tmp << (64 - 8));
+ b8 -= b9 + k12;
+ b9 -= k13;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 47) | (tmp << (64 - 47));
+ b6 -= b7 + k10;
+ b7 -= k11;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 8) | (tmp << (64 - 8));
+ b4 -= b5 + k8;
+ b5 -= k9;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b3 + k6;
+ b3 -= k7;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 24) | (tmp << (64 - 24));
+ b0 -= b1 + k4;
+ b1 -= k5;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 20) | (tmp << (64 - 20));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 37) | (tmp << (64 - 37));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 31) | (tmp << (64 - 31));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 52) | (tmp << (64 - 52));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 35) | (tmp << (64 - 35));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 48) | (tmp << (64 - 48));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 25) | (tmp << (64 - 25));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 44) | (tmp << (64 - 44));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 19) | (tmp << (64 - 19));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 47) | (tmp << (64 - 47));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 44) | (tmp << (64 - 44));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 53) | (tmp << (64 - 53));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 4) | (tmp << (64 - 4));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 56) | (tmp << (64 - 56));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 34) | (tmp << (64 - 34));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 16) | (tmp << (64 - 16));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 30) | (tmp << (64 - 30));
+ b14 -= b15 + k0 + t1;
+ b15 -= k1 + 3;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 44) | (tmp << (64 - 44));
+ b12 -= b13 + k15;
+ b13 -= k16 + t0;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 47) | (tmp << (64 - 47));
+ b10 -= b11 + k13;
+ b11 -= k14;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 12) | (tmp << (64 - 12));
+ b8 -= b9 + k11;
+ b9 -= k12;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b6 -= b7 + k9;
+ b7 -= k10;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 37) | (tmp << (64 - 37));
+ b4 -= b5 + k7;
+ b5 -= k8;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 9) | (tmp << (64 - 9));
+ b2 -= b3 + k5;
+ b3 -= k6;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b0 -= b1 + k3;
+ b1 -= k4;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 25) | (tmp << (64 - 25));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 28) | (tmp << (64 - 28));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 47) | (tmp << (64 - 47));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 41) | (tmp << (64 - 41));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 48) | (tmp << (64 - 48));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 20) | (tmp << (64 - 20));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 59) | (tmp << (64 - 59));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 41) | (tmp << (64 - 41));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 34) | (tmp << (64 - 34));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 4) | (tmp << (64 - 4));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 33) | (tmp << (64 - 33));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 52) | (tmp << (64 - 52));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 18) | (tmp << (64 - 18));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 49) | (tmp << (64 - 49));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 55) | (tmp << (64 - 55));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 19) | (tmp << (64 - 19));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 38) | (tmp << (64 - 38));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 37) | (tmp << (64 - 37));
+ b14 -= b15 + k16 + t0;
+ b15 -= k0 + 2;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 22) | (tmp << (64 - 22));
+ b12 -= b13 + k14;
+ b13 -= k15 + t2;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b11 + k12;
+ b11 -= k13;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 8) | (tmp << (64 - 8));
+ b8 -= b9 + k10;
+ b9 -= k11;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 47) | (tmp << (64 - 47));
+ b6 -= b7 + k8;
+ b7 -= k9;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 8) | (tmp << (64 - 8));
+ b4 -= b5 + k6;
+ b5 -= k7;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b3 + k4;
+ b3 -= k5;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 24) | (tmp << (64 - 24));
+ b0 -= b1 + k2;
+ b1 -= k3;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 20) | (tmp << (64 - 20));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 37) | (tmp << (64 - 37));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 31) | (tmp << (64 - 31));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 52) | (tmp << (64 - 52));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 35) | (tmp << (64 - 35));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 48) | (tmp << (64 - 48));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 25) | (tmp << (64 - 25));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 44) | (tmp << (64 - 44));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 19) | (tmp << (64 - 19));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 47) | (tmp << (64 - 47));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 44) | (tmp << (64 - 44));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 42) | (tmp << (64 - 42));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 53) | (tmp << (64 - 53));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 4) | (tmp << (64 - 4));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 56) | (tmp << (64 - 56));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 34) | (tmp << (64 - 34));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 16) | (tmp << (64 - 16));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 30) | (tmp << (64 - 30));
+ b14 -= b15 + k15 + t2;
+ b15 -= k16 + 1;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 44) | (tmp << (64 - 44));
+ b12 -= b13 + k13;
+ b13 -= k14 + t1;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 47) | (tmp << (64 - 47));
+ b10 -= b11 + k11;
+ b11 -= k12;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 12) | (tmp << (64 - 12));
+ b8 -= b9 + k9;
+ b9 -= k10;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 31) | (tmp << (64 - 31));
+ b6 -= b7 + k7;
+ b7 -= k8;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 37) | (tmp << (64 - 37));
+ b4 -= b5 + k5;
+ b5 -= k6;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 9) | (tmp << (64 - 9));
+ b2 -= b3 + k3;
+ b3 -= k4;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 41) | (tmp << (64 - 41));
+ b0 -= b1 + k1;
+ b1 -= k2;
+
+ tmp = b7 ^ b12;
+ b7 = (tmp >> 25) | (tmp << (64 - 25));
+ b12 -= b7;
+
+ tmp = b3 ^ b10;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b10 -= b3;
+
+ tmp = b5 ^ b8;
+ b5 = (tmp >> 28) | (tmp << (64 - 28));
+ b8 -= b5;
+
+ tmp = b1 ^ b14;
+ b1 = (tmp >> 47) | (tmp << (64 - 47));
+ b14 -= b1;
+
+ tmp = b9 ^ b4;
+ b9 = (tmp >> 41) | (tmp << (64 - 41));
+ b4 -= b9;
+
+ tmp = b13 ^ b6;
+ b13 = (tmp >> 48) | (tmp << (64 - 48));
+ b6 -= b13;
+
+ tmp = b11 ^ b2;
+ b11 = (tmp >> 20) | (tmp << (64 - 20));
+ b2 -= b11;
+
+ tmp = b15 ^ b0;
+ b15 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b15;
+
+ tmp = b9 ^ b10;
+ b9 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b9;
+
+ tmp = b11 ^ b8;
+ b11 = (tmp >> 59) | (tmp << (64 - 59));
+ b8 -= b11;
+
+ tmp = b13 ^ b14;
+ b13 = (tmp >> 41) | (tmp << (64 - 41));
+ b14 -= b13;
+
+ tmp = b15 ^ b12;
+ b15 = (tmp >> 34) | (tmp << (64 - 34));
+ b12 -= b15;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b6 -= b1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 51) | (tmp << (64 - 51));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 4) | (tmp << (64 - 4));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 33) | (tmp << (64 - 33));
+ b0 -= b7;
+
+ tmp = b1 ^ b8;
+ b1 = (tmp >> 52) | (tmp << (64 - 52));
+ b8 -= b1;
+
+ tmp = b5 ^ b14;
+ b5 = (tmp >> 23) | (tmp << (64 - 23));
+ b14 -= b5;
+
+ tmp = b3 ^ b12;
+ b3 = (tmp >> 18) | (tmp << (64 - 18));
+ b12 -= b3;
+
+ tmp = b7 ^ b10;
+ b7 = (tmp >> 49) | (tmp << (64 - 49));
+ b10 -= b7;
+
+ tmp = b15 ^ b4;
+ b15 = (tmp >> 55) | (tmp << (64 - 55));
+ b4 -= b15;
+
+ tmp = b11 ^ b6;
+ b11 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b11;
+
+ tmp = b13 ^ b2;
+ b13 = (tmp >> 19) | (tmp << (64 - 19));
+ b2 -= b13;
+
+ tmp = b9 ^ b0;
+ b9 = (tmp >> 38) | (tmp << (64 - 38));
+ b0 -= b9;
+
+ tmp = b15 ^ b14;
+ b15 = (tmp >> 37) | (tmp << (64 - 37));
+ b14 -= b15 + k14 + t1;
+ b15 -= k15;
+
+ tmp = b13 ^ b12;
+ b13 = (tmp >> 22) | (tmp << (64 - 22));
+ b12 -= b13 + k12;
+ b13 -= k13 + t0;
+
+ tmp = b11 ^ b10;
+ b11 = (tmp >> 17) | (tmp << (64 - 17));
+ b10 -= b11 + k10;
+ b11 -= k11;
+
+ tmp = b9 ^ b8;
+ b9 = (tmp >> 8) | (tmp << (64 - 8));
+ b8 -= b9 + k8;
+ b9 -= k9;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 47) | (tmp << (64 - 47));
+ b6 -= b7 + k6;
+ b7 -= k7;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 8) | (tmp << (64 - 8));
+ b4 -= b5 + k4;
+ b5 -= k5;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b3 + k2;
+ b3 -= k3;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 24) | (tmp << (64 - 24));
+ b0 -= b1 + k0;
+ b1 -= k1;
+
+ output[15] = b15;
+ output[14] = b14;
+ output[13] = b13;
+ output[12] = b12;
+ output[11] = b11;
+ output[10] = b10;
+ output[9] = b9;
+ output[8] = b8;
+ output[7] = b7;
+ output[6] = b6;
+ output[5] = b5;
+ output[4] = b4;
+ output[3] = b3;
+ output[2] = b2;
+ output[1] = b1;
+ output[0] = b0;
+}
--- /dev/null
+#include <linux/string.h>
+#include <threefishApi.h>
+
+
+void threefishEncrypt256(struct threefish_key *keyCtx, u64 *input, u64 *output)
+{
+ u64 b0 = input[0], b1 = input[1],
+ b2 = input[2], b3 = input[3];
+ u64 k0 = keyCtx->key[0], k1 = keyCtx->key[1],
+ k2 = keyCtx->key[2], k3 = keyCtx->key[3],
+ k4 = keyCtx->key[4];
+ u64 t0 = keyCtx->tweak[0], t1 = keyCtx->tweak[1],
+ t2 = keyCtx->tweak[2];
+
+ b1 += k1 + t0;
+ b0 += b1 + k0;
+ b1 = ((b1 << 14) | (b1 >> (64 - 14))) ^ b0;
+
+ b3 += k3;
+ b2 += b3 + k2 + t1;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 52) | (b3 >> (64 - 52))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 57) | (b1 >> (64 - 57))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 40) | (b3 >> (64 - 40))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 5) | (b3 >> (64 - 5))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 37) | (b1 >> (64 - 37))) ^ b2;
+
+ b1 += k2 + t1;
+ b0 += b1 + k1;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b0;
+
+ b3 += k4 + 1;
+ b2 += b3 + k3 + t2;
+ b3 = ((b3 << 33) | (b3 >> (64 - 33))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 46) | (b3 >> (64 - 46))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 12) | (b1 >> (64 - 12))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 58) | (b1 >> (64 - 58))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 32) | (b3 >> (64 - 32))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 32) | (b1 >> (64 - 32))) ^ b2;
+
+
+ b1 += k3 + t2;
+ b0 += b1 + k2;
+ b1 = ((b1 << 14) | (b1 >> (64 - 14))) ^ b0;
+
+ b3 += k0 + 2;
+ b2 += b3 + k4 + t0;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 52) | (b3 >> (64 - 52))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 57) | (b1 >> (64 - 57))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 40) | (b3 >> (64 - 40))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 5) | (b3 >> (64 - 5))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 37) | (b1 >> (64 - 37))) ^ b2;
+
+ b1 += k4 + t0;
+ b0 += b1 + k3;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b0;
+
+ b3 += k1 + 3;
+ b2 += b3 + k0 + t1;
+ b3 = ((b3 << 33) | (b3 >> (64 - 33))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 46) | (b3 >> (64 - 46))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 12) | (b1 >> (64 - 12))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 58) | (b1 >> (64 - 58))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 32) | (b3 >> (64 - 32))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 32) | (b1 >> (64 - 32))) ^ b2;
+
+
+ b1 += k0 + t1;
+ b0 += b1 + k4;
+ b1 = ((b1 << 14) | (b1 >> (64 - 14))) ^ b0;
+
+ b3 += k2 + 4;
+ b2 += b3 + k1 + t2;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 52) | (b3 >> (64 - 52))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 57) | (b1 >> (64 - 57))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 40) | (b3 >> (64 - 40))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 5) | (b3 >> (64 - 5))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 37) | (b1 >> (64 - 37))) ^ b2;
+
+ b1 += k1 + t2;
+ b0 += b1 + k0;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b0;
+
+ b3 += k3 + 5;
+ b2 += b3 + k2 + t0;
+ b3 = ((b3 << 33) | (b3 >> (64 - 33))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 46) | (b3 >> (64 - 46))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 12) | (b1 >> (64 - 12))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 58) | (b1 >> (64 - 58))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 32) | (b3 >> (64 - 32))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 32) | (b1 >> (64 - 32))) ^ b2;
+
+
+ b1 += k2 + t0;
+ b0 += b1 + k1;
+ b1 = ((b1 << 14) | (b1 >> (64 - 14))) ^ b0;
+
+ b3 += k4 + 6;
+ b2 += b3 + k3 + t1;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 52) | (b3 >> (64 - 52))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 57) | (b1 >> (64 - 57))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 40) | (b3 >> (64 - 40))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 5) | (b3 >> (64 - 5))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 37) | (b1 >> (64 - 37))) ^ b2;
+
+ b1 += k3 + t1;
+ b0 += b1 + k2;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b0;
+
+ b3 += k0 + 7;
+ b2 += b3 + k4 + t2;
+ b3 = ((b3 << 33) | (b3 >> (64 - 33))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 46) | (b3 >> (64 - 46))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 12) | (b1 >> (64 - 12))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 58) | (b1 >> (64 - 58))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 32) | (b3 >> (64 - 32))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 32) | (b1 >> (64 - 32))) ^ b2;
+
+
+ b1 += k4 + t2;
+ b0 += b1 + k3;
+ b1 = ((b1 << 14) | (b1 >> (64 - 14))) ^ b0;
+
+ b3 += k1 + 8;
+ b2 += b3 + k0 + t0;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 52) | (b3 >> (64 - 52))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 57) | (b1 >> (64 - 57))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 40) | (b3 >> (64 - 40))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 5) | (b3 >> (64 - 5))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 37) | (b1 >> (64 - 37))) ^ b2;
+
+ b1 += k0 + t0;
+ b0 += b1 + k4;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b0;
+
+ b3 += k2 + 9;
+ b2 += b3 + k1 + t1;
+ b3 = ((b3 << 33) | (b3 >> (64 - 33))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 46) | (b3 >> (64 - 46))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 12) | (b1 >> (64 - 12))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 58) | (b1 >> (64 - 58))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 32) | (b3 >> (64 - 32))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 32) | (b1 >> (64 - 32))) ^ b2;
+
+
+ b1 += k1 + t1;
+ b0 += b1 + k0;
+ b1 = ((b1 << 14) | (b1 >> (64 - 14))) ^ b0;
+
+ b3 += k3 + 10;
+ b2 += b3 + k2 + t2;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 52) | (b3 >> (64 - 52))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 57) | (b1 >> (64 - 57))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 40) | (b3 >> (64 - 40))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 5) | (b3 >> (64 - 5))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 37) | (b1 >> (64 - 37))) ^ b2;
+
+ b1 += k2 + t2;
+ b0 += b1 + k1;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b0;
+
+ b3 += k4 + 11;
+ b2 += b3 + k3 + t0;
+ b3 = ((b3 << 33) | (b3 >> (64 - 33))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 46) | (b3 >> (64 - 46))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 12) | (b1 >> (64 - 12))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 58) | (b1 >> (64 - 58))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 32) | (b3 >> (64 - 32))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 32) | (b1 >> (64 - 32))) ^ b2;
+
+
+ b1 += k3 + t0;
+ b0 += b1 + k2;
+ b1 = ((b1 << 14) | (b1 >> (64 - 14))) ^ b0;
+
+ b3 += k0 + 12;
+ b2 += b3 + k4 + t1;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 52) | (b3 >> (64 - 52))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 57) | (b1 >> (64 - 57))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 40) | (b3 >> (64 - 40))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 5) | (b3 >> (64 - 5))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 37) | (b1 >> (64 - 37))) ^ b2;
+
+ b1 += k4 + t1;
+ b0 += b1 + k3;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b0;
+
+ b3 += k1 + 13;
+ b2 += b3 + k0 + t2;
+ b3 = ((b3 << 33) | (b3 >> (64 - 33))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 46) | (b3 >> (64 - 46))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 12) | (b1 >> (64 - 12))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 58) | (b1 >> (64 - 58))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 32) | (b3 >> (64 - 32))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 32) | (b1 >> (64 - 32))) ^ b2;
+
+
+ b1 += k0 + t2;
+ b0 += b1 + k4;
+ b1 = ((b1 << 14) | (b1 >> (64 - 14))) ^ b0;
+
+ b3 += k2 + 14;
+ b2 += b3 + k1 + t0;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 52) | (b3 >> (64 - 52))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 57) | (b1 >> (64 - 57))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 40) | (b3 >> (64 - 40))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 5) | (b3 >> (64 - 5))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 37) | (b1 >> (64 - 37))) ^ b2;
+
+ b1 += k1 + t0;
+ b0 += b1 + k0;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b0;
+
+ b3 += k3 + 15;
+ b2 += b3 + k2 + t1;
+ b3 = ((b3 << 33) | (b3 >> (64 - 33))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 46) | (b3 >> (64 - 46))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 12) | (b1 >> (64 - 12))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 58) | (b1 >> (64 - 58))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 32) | (b3 >> (64 - 32))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 32) | (b1 >> (64 - 32))) ^ b2;
+
+
+ b1 += k2 + t1;
+ b0 += b1 + k1;
+ b1 = ((b1 << 14) | (b1 >> (64 - 14))) ^ b0;
+
+ b3 += k4 + 16;
+ b2 += b3 + k3 + t2;
+ b3 = ((b3 << 16) | (b3 >> (64 - 16))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 52) | (b3 >> (64 - 52))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 57) | (b1 >> (64 - 57))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 23) | (b1 >> (64 - 23))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 40) | (b3 >> (64 - 40))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 5) | (b3 >> (64 - 5))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 37) | (b1 >> (64 - 37))) ^ b2;
+
+ b1 += k3 + t2;
+ b0 += b1 + k2;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b0;
+
+ b3 += k0 + 17;
+ b2 += b3 + k4 + t0;
+ b3 = ((b3 << 33) | (b3 >> (64 - 33))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 46) | (b3 >> (64 - 46))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 12) | (b1 >> (64 - 12))) ^ b2;
+
+ b0 += b1;
+ b1 = ((b1 << 58) | (b1 >> (64 - 58))) ^ b0;
+
+ b2 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b2;
+
+ b0 += b3;
+ b3 = ((b3 << 32) | (b3 >> (64 - 32))) ^ b0;
+
+ b2 += b1;
+ b1 = ((b1 << 32) | (b1 >> (64 - 32))) ^ b2;
+
+ output[0] = b0 + k3;
+ output[1] = b1 + k4 + t0;
+ output[2] = b2 + k0 + t1;
+ output[3] = b3 + k1 + 18;
+}
+
+void threefishDecrypt256(struct threefish_key *keyCtx, u64 *input, u64 *output)
+{
+ u64 b0 = input[0], b1 = input[1],
+ b2 = input[2], b3 = input[3];
+ u64 k0 = keyCtx->key[0], k1 = keyCtx->key[1],
+ k2 = keyCtx->key[2], k3 = keyCtx->key[3],
+ k4 = keyCtx->key[4];
+ u64 t0 = keyCtx->tweak[0], t1 = keyCtx->tweak[1],
+ t2 = keyCtx->tweak[2];
+
+ u64 tmp;
+
+ b0 -= k3;
+ b1 -= k4 + t0;
+ b2 -= k0 + t1;
+ b3 -= k1 + 18;
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 32) | (tmp << (64 - 32));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 32) | (tmp << (64 - 32));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 58) | (tmp << (64 - 58));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 12) | (tmp << (64 - 12));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b0 -= b1 + k2;
+ b1 -= k3 + t2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b3 + k4 + t0;
+ b3 -= k0 + 17;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 37) | (tmp << (64 - 37));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 40) | (tmp << (64 - 40));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 52) | (tmp << (64 - 52));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 57) | (tmp << (64 - 57));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 14) | (tmp << (64 - 14));
+ b0 -= b1 + k1;
+ b1 -= k2 + t1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b2 -= b3 + k3 + t2;
+ b3 -= k4 + 16;
+
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 32) | (tmp << (64 - 32));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 32) | (tmp << (64 - 32));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 58) | (tmp << (64 - 58));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 12) | (tmp << (64 - 12));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b0 -= b1 + k0;
+ b1 -= k1 + t0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b3 + k2 + t1;
+ b3 -= k3 + 15;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 37) | (tmp << (64 - 37));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 40) | (tmp << (64 - 40));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 52) | (tmp << (64 - 52));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 57) | (tmp << (64 - 57));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 14) | (tmp << (64 - 14));
+ b0 -= b1 + k4;
+ b1 -= k0 + t2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b2 -= b3 + k1 + t0;
+ b3 -= k2 + 14;
+
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 32) | (tmp << (64 - 32));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 32) | (tmp << (64 - 32));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 58) | (tmp << (64 - 58));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 12) | (tmp << (64 - 12));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b0 -= b1 + k3;
+ b1 -= k4 + t1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b3 + k0 + t2;
+ b3 -= k1 + 13;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 37) | (tmp << (64 - 37));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 40) | (tmp << (64 - 40));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 52) | (tmp << (64 - 52));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 57) | (tmp << (64 - 57));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 14) | (tmp << (64 - 14));
+ b0 -= b1 + k2;
+ b1 -= k3 + t0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b2 -= b3 + k4 + t1;
+ b3 -= k0 + 12;
+
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 32) | (tmp << (64 - 32));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 32) | (tmp << (64 - 32));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 58) | (tmp << (64 - 58));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 12) | (tmp << (64 - 12));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b0 -= b1 + k1;
+ b1 -= k2 + t2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b3 + k3 + t0;
+ b3 -= k4 + 11;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 37) | (tmp << (64 - 37));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 40) | (tmp << (64 - 40));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 52) | (tmp << (64 - 52));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 57) | (tmp << (64 - 57));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 14) | (tmp << (64 - 14));
+ b0 -= b1 + k0;
+ b1 -= k1 + t1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b2 -= b3 + k2 + t2;
+ b3 -= k3 + 10;
+
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 32) | (tmp << (64 - 32));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 32) | (tmp << (64 - 32));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 58) | (tmp << (64 - 58));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 12) | (tmp << (64 - 12));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b0 -= b1 + k4;
+ b1 -= k0 + t0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b3 + k1 + t1;
+ b3 -= k2 + 9;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 37) | (tmp << (64 - 37));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 40) | (tmp << (64 - 40));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 52) | (tmp << (64 - 52));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 57) | (tmp << (64 - 57));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 14) | (tmp << (64 - 14));
+ b0 -= b1 + k3;
+ b1 -= k4 + t2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b2 -= b3 + k0 + t0;
+ b3 -= k1 + 8;
+
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 32) | (tmp << (64 - 32));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 32) | (tmp << (64 - 32));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 58) | (tmp << (64 - 58));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 12) | (tmp << (64 - 12));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b0 -= b1 + k2;
+ b1 -= k3 + t1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b3 + k4 + t2;
+ b3 -= k0 + 7;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 37) | (tmp << (64 - 37));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 40) | (tmp << (64 - 40));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 52) | (tmp << (64 - 52));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 57) | (tmp << (64 - 57));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 14) | (tmp << (64 - 14));
+ b0 -= b1 + k1;
+ b1 -= k2 + t0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b2 -= b3 + k3 + t1;
+ b3 -= k4 + 6;
+
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 32) | (tmp << (64 - 32));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 32) | (tmp << (64 - 32));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 58) | (tmp << (64 - 58));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 12) | (tmp << (64 - 12));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b0 -= b1 + k0;
+ b1 -= k1 + t2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b3 + k2 + t0;
+ b3 -= k3 + 5;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 37) | (tmp << (64 - 37));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 40) | (tmp << (64 - 40));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 52) | (tmp << (64 - 52));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 57) | (tmp << (64 - 57));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 14) | (tmp << (64 - 14));
+ b0 -= b1 + k4;
+ b1 -= k0 + t1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b2 -= b3 + k1 + t2;
+ b3 -= k2 + 4;
+
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 32) | (tmp << (64 - 32));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 32) | (tmp << (64 - 32));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 58) | (tmp << (64 - 58));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 12) | (tmp << (64 - 12));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b0 -= b1 + k3;
+ b1 -= k4 + t0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b3 + k0 + t1;
+ b3 -= k1 + 3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 37) | (tmp << (64 - 37));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 40) | (tmp << (64 - 40));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 52) | (tmp << (64 - 52));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 57) | (tmp << (64 - 57));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 14) | (tmp << (64 - 14));
+ b0 -= b1 + k2;
+ b1 -= k3 + t2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b2 -= b3 + k4 + t0;
+ b3 -= k0 + 2;
+
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 32) | (tmp << (64 - 32));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 32) | (tmp << (64 - 32));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 58) | (tmp << (64 - 58));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 12) | (tmp << (64 - 12));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b0 -= b1 + k1;
+ b1 -= k2 + t1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b3 + k3 + t2;
+ b3 -= k4 + 1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 5) | (tmp << (64 - 5));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 37) | (tmp << (64 - 37));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 23) | (tmp << (64 - 23));
+ b0 -= b1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 40) | (tmp << (64 - 40));
+ b2 -= b3;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 52) | (tmp << (64 - 52));
+ b0 -= b3;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 57) | (tmp << (64 - 57));
+ b2 -= b1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 14) | (tmp << (64 - 14));
+ b0 -= b1 + k0;
+ b1 -= k1 + t0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 16) | (tmp << (64 - 16));
+ b2 -= b3 + k2 + t1;
+ b3 -= k3;
+
+ output[0] = b0;
+ output[1] = b1;
+ output[2] = b2;
+ output[3] = b3;
+}
--- /dev/null
+#include <linux/string.h>
+#include <threefishApi.h>
+
+
+void threefishEncrypt512(struct threefish_key *keyCtx, u64 *input, u64 *output)
+{
+ u64 b0 = input[0], b1 = input[1],
+ b2 = input[2], b3 = input[3],
+ b4 = input[4], b5 = input[5],
+ b6 = input[6], b7 = input[7];
+ u64 k0 = keyCtx->key[0], k1 = keyCtx->key[1],
+ k2 = keyCtx->key[2], k3 = keyCtx->key[3],
+ k4 = keyCtx->key[4], k5 = keyCtx->key[5],
+ k6 = keyCtx->key[6], k7 = keyCtx->key[7],
+ k8 = keyCtx->key[8];
+ u64 t0 = keyCtx->tweak[0], t1 = keyCtx->tweak[1],
+ t2 = keyCtx->tweak[2];
+
+ b1 += k1;
+ b0 += b1 + k0;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b0;
+
+ b3 += k3;
+ b2 += b3 + k2;
+ b3 = ((b3 << 36) | (b3 >> (64 - 36))) ^ b2;
+
+ b5 += k5 + t0;
+ b4 += b5 + k4;
+ b5 = ((b5 << 19) | (b5 >> (64 - 19))) ^ b4;
+
+ b7 += k7;
+ b6 += b7 + k6 + t1;
+ b7 = ((b7 << 37) | (b7 >> (64 - 37))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 33) | (b1 >> (64 - 33))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 27) | (b7 >> (64 - 27))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 14) | (b5 >> (64 - 14))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 42) | (b3 >> (64 - 42))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 17) | (b1 >> (64 - 17))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 49) | (b3 >> (64 - 49))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 36) | (b5 >> (64 - 36))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 39) | (b7 >> (64 - 39))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 44) | (b1 >> (64 - 44))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 9) | (b7 >> (64 - 9))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 54) | (b5 >> (64 - 54))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 56) | (b3 >> (64 - 56))) ^ b4;
+
+ b1 += k2;
+ b0 += b1 + k1;
+ b1 = ((b1 << 39) | (b1 >> (64 - 39))) ^ b0;
+
+ b3 += k4;
+ b2 += b3 + k3;
+ b3 = ((b3 << 30) | (b3 >> (64 - 30))) ^ b2;
+
+ b5 += k6 + t1;
+ b4 += b5 + k5;
+ b5 = ((b5 << 34) | (b5 >> (64 - 34))) ^ b4;
+
+ b7 += k8 + 1;
+ b6 += b7 + k7 + t2;
+ b7 = ((b7 << 24) | (b7 >> (64 - 24))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 50) | (b7 >> (64 - 50))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 10) | (b5 >> (64 - 10))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 17) | (b3 >> (64 - 17))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 29) | (b3 >> (64 - 29))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 39) | (b5 >> (64 - 39))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 43) | (b7 >> (64 - 43))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 8) | (b1 >> (64 - 8))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 35) | (b7 >> (64 - 35))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 56) | (b5 >> (64 - 56))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b4;
+
+ b1 += k3;
+ b0 += b1 + k2;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b0;
+
+ b3 += k5;
+ b2 += b3 + k4;
+ b3 = ((b3 << 36) | (b3 >> (64 - 36))) ^ b2;
+
+ b5 += k7 + t2;
+ b4 += b5 + k6;
+ b5 = ((b5 << 19) | (b5 >> (64 - 19))) ^ b4;
+
+ b7 += k0 + 2;
+ b6 += b7 + k8 + t0;
+ b7 = ((b7 << 37) | (b7 >> (64 - 37))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 33) | (b1 >> (64 - 33))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 27) | (b7 >> (64 - 27))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 14) | (b5 >> (64 - 14))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 42) | (b3 >> (64 - 42))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 17) | (b1 >> (64 - 17))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 49) | (b3 >> (64 - 49))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 36) | (b5 >> (64 - 36))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 39) | (b7 >> (64 - 39))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 44) | (b1 >> (64 - 44))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 9) | (b7 >> (64 - 9))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 54) | (b5 >> (64 - 54))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 56) | (b3 >> (64 - 56))) ^ b4;
+
+ b1 += k4;
+ b0 += b1 + k3;
+ b1 = ((b1 << 39) | (b1 >> (64 - 39))) ^ b0;
+
+ b3 += k6;
+ b2 += b3 + k5;
+ b3 = ((b3 << 30) | (b3 >> (64 - 30))) ^ b2;
+
+ b5 += k8 + t0;
+ b4 += b5 + k7;
+ b5 = ((b5 << 34) | (b5 >> (64 - 34))) ^ b4;
+
+ b7 += k1 + 3;
+ b6 += b7 + k0 + t1;
+ b7 = ((b7 << 24) | (b7 >> (64 - 24))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 50) | (b7 >> (64 - 50))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 10) | (b5 >> (64 - 10))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 17) | (b3 >> (64 - 17))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 29) | (b3 >> (64 - 29))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 39) | (b5 >> (64 - 39))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 43) | (b7 >> (64 - 43))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 8) | (b1 >> (64 - 8))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 35) | (b7 >> (64 - 35))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 56) | (b5 >> (64 - 56))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b4;
+
+ b1 += k5;
+ b0 += b1 + k4;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b0;
+
+ b3 += k7;
+ b2 += b3 + k6;
+ b3 = ((b3 << 36) | (b3 >> (64 - 36))) ^ b2;
+
+ b5 += k0 + t1;
+ b4 += b5 + k8;
+ b5 = ((b5 << 19) | (b5 >> (64 - 19))) ^ b4;
+
+ b7 += k2 + 4;
+ b6 += b7 + k1 + t2;
+ b7 = ((b7 << 37) | (b7 >> (64 - 37))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 33) | (b1 >> (64 - 33))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 27) | (b7 >> (64 - 27))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 14) | (b5 >> (64 - 14))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 42) | (b3 >> (64 - 42))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 17) | (b1 >> (64 - 17))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 49) | (b3 >> (64 - 49))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 36) | (b5 >> (64 - 36))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 39) | (b7 >> (64 - 39))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 44) | (b1 >> (64 - 44))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 9) | (b7 >> (64 - 9))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 54) | (b5 >> (64 - 54))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 56) | (b3 >> (64 - 56))) ^ b4;
+
+ b1 += k6;
+ b0 += b1 + k5;
+ b1 = ((b1 << 39) | (b1 >> (64 - 39))) ^ b0;
+
+ b3 += k8;
+ b2 += b3 + k7;
+ b3 = ((b3 << 30) | (b3 >> (64 - 30))) ^ b2;
+
+ b5 += k1 + t2;
+ b4 += b5 + k0;
+ b5 = ((b5 << 34) | (b5 >> (64 - 34))) ^ b4;
+
+ b7 += k3 + 5;
+ b6 += b7 + k2 + t0;
+ b7 = ((b7 << 24) | (b7 >> (64 - 24))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 50) | (b7 >> (64 - 50))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 10) | (b5 >> (64 - 10))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 17) | (b3 >> (64 - 17))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 29) | (b3 >> (64 - 29))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 39) | (b5 >> (64 - 39))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 43) | (b7 >> (64 - 43))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 8) | (b1 >> (64 - 8))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 35) | (b7 >> (64 - 35))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 56) | (b5 >> (64 - 56))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b4;
+
+ b1 += k7;
+ b0 += b1 + k6;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b0;
+
+ b3 += k0;
+ b2 += b3 + k8;
+ b3 = ((b3 << 36) | (b3 >> (64 - 36))) ^ b2;
+
+ b5 += k2 + t0;
+ b4 += b5 + k1;
+ b5 = ((b5 << 19) | (b5 >> (64 - 19))) ^ b4;
+
+ b7 += k4 + 6;
+ b6 += b7 + k3 + t1;
+ b7 = ((b7 << 37) | (b7 >> (64 - 37))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 33) | (b1 >> (64 - 33))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 27) | (b7 >> (64 - 27))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 14) | (b5 >> (64 - 14))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 42) | (b3 >> (64 - 42))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 17) | (b1 >> (64 - 17))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 49) | (b3 >> (64 - 49))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 36) | (b5 >> (64 - 36))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 39) | (b7 >> (64 - 39))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 44) | (b1 >> (64 - 44))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 9) | (b7 >> (64 - 9))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 54) | (b5 >> (64 - 54))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 56) | (b3 >> (64 - 56))) ^ b4;
+
+ b1 += k8;
+ b0 += b1 + k7;
+ b1 = ((b1 << 39) | (b1 >> (64 - 39))) ^ b0;
+
+ b3 += k1;
+ b2 += b3 + k0;
+ b3 = ((b3 << 30) | (b3 >> (64 - 30))) ^ b2;
+
+ b5 += k3 + t1;
+ b4 += b5 + k2;
+ b5 = ((b5 << 34) | (b5 >> (64 - 34))) ^ b4;
+
+ b7 += k5 + 7;
+ b6 += b7 + k4 + t2;
+ b7 = ((b7 << 24) | (b7 >> (64 - 24))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 50) | (b7 >> (64 - 50))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 10) | (b5 >> (64 - 10))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 17) | (b3 >> (64 - 17))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 29) | (b3 >> (64 - 29))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 39) | (b5 >> (64 - 39))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 43) | (b7 >> (64 - 43))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 8) | (b1 >> (64 - 8))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 35) | (b7 >> (64 - 35))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 56) | (b5 >> (64 - 56))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b4;
+
+ b1 += k0;
+ b0 += b1 + k8;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b0;
+
+ b3 += k2;
+ b2 += b3 + k1;
+ b3 = ((b3 << 36) | (b3 >> (64 - 36))) ^ b2;
+
+ b5 += k4 + t2;
+ b4 += b5 + k3;
+ b5 = ((b5 << 19) | (b5 >> (64 - 19))) ^ b4;
+
+ b7 += k6 + 8;
+ b6 += b7 + k5 + t0;
+ b7 = ((b7 << 37) | (b7 >> (64 - 37))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 33) | (b1 >> (64 - 33))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 27) | (b7 >> (64 - 27))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 14) | (b5 >> (64 - 14))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 42) | (b3 >> (64 - 42))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 17) | (b1 >> (64 - 17))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 49) | (b3 >> (64 - 49))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 36) | (b5 >> (64 - 36))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 39) | (b7 >> (64 - 39))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 44) | (b1 >> (64 - 44))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 9) | (b7 >> (64 - 9))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 54) | (b5 >> (64 - 54))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 56) | (b3 >> (64 - 56))) ^ b4;
+
+ b1 += k1;
+ b0 += b1 + k0;
+ b1 = ((b1 << 39) | (b1 >> (64 - 39))) ^ b0;
+
+ b3 += k3;
+ b2 += b3 + k2;
+ b3 = ((b3 << 30) | (b3 >> (64 - 30))) ^ b2;
+
+ b5 += k5 + t0;
+ b4 += b5 + k4;
+ b5 = ((b5 << 34) | (b5 >> (64 - 34))) ^ b4;
+
+ b7 += k7 + 9;
+ b6 += b7 + k6 + t1;
+ b7 = ((b7 << 24) | (b7 >> (64 - 24))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 50) | (b7 >> (64 - 50))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 10) | (b5 >> (64 - 10))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 17) | (b3 >> (64 - 17))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 29) | (b3 >> (64 - 29))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 39) | (b5 >> (64 - 39))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 43) | (b7 >> (64 - 43))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 8) | (b1 >> (64 - 8))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 35) | (b7 >> (64 - 35))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 56) | (b5 >> (64 - 56))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b4;
+
+ b1 += k2;
+ b0 += b1 + k1;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b0;
+
+ b3 += k4;
+ b2 += b3 + k3;
+ b3 = ((b3 << 36) | (b3 >> (64 - 36))) ^ b2;
+
+ b5 += k6 + t1;
+ b4 += b5 + k5;
+ b5 = ((b5 << 19) | (b5 >> (64 - 19))) ^ b4;
+
+ b7 += k8 + 10;
+ b6 += b7 + k7 + t2;
+ b7 = ((b7 << 37) | (b7 >> (64 - 37))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 33) | (b1 >> (64 - 33))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 27) | (b7 >> (64 - 27))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 14) | (b5 >> (64 - 14))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 42) | (b3 >> (64 - 42))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 17) | (b1 >> (64 - 17))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 49) | (b3 >> (64 - 49))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 36) | (b5 >> (64 - 36))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 39) | (b7 >> (64 - 39))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 44) | (b1 >> (64 - 44))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 9) | (b7 >> (64 - 9))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 54) | (b5 >> (64 - 54))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 56) | (b3 >> (64 - 56))) ^ b4;
+
+ b1 += k3;
+ b0 += b1 + k2;
+ b1 = ((b1 << 39) | (b1 >> (64 - 39))) ^ b0;
+
+ b3 += k5;
+ b2 += b3 + k4;
+ b3 = ((b3 << 30) | (b3 >> (64 - 30))) ^ b2;
+
+ b5 += k7 + t2;
+ b4 += b5 + k6;
+ b5 = ((b5 << 34) | (b5 >> (64 - 34))) ^ b4;
+
+ b7 += k0 + 11;
+ b6 += b7 + k8 + t0;
+ b7 = ((b7 << 24) | (b7 >> (64 - 24))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 50) | (b7 >> (64 - 50))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 10) | (b5 >> (64 - 10))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 17) | (b3 >> (64 - 17))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 29) | (b3 >> (64 - 29))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 39) | (b5 >> (64 - 39))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 43) | (b7 >> (64 - 43))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 8) | (b1 >> (64 - 8))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 35) | (b7 >> (64 - 35))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 56) | (b5 >> (64 - 56))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b4;
+
+ b1 += k4;
+ b0 += b1 + k3;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b0;
+
+ b3 += k6;
+ b2 += b3 + k5;
+ b3 = ((b3 << 36) | (b3 >> (64 - 36))) ^ b2;
+
+ b5 += k8 + t0;
+ b4 += b5 + k7;
+ b5 = ((b5 << 19) | (b5 >> (64 - 19))) ^ b4;
+
+ b7 += k1 + 12;
+ b6 += b7 + k0 + t1;
+ b7 = ((b7 << 37) | (b7 >> (64 - 37))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 33) | (b1 >> (64 - 33))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 27) | (b7 >> (64 - 27))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 14) | (b5 >> (64 - 14))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 42) | (b3 >> (64 - 42))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 17) | (b1 >> (64 - 17))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 49) | (b3 >> (64 - 49))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 36) | (b5 >> (64 - 36))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 39) | (b7 >> (64 - 39))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 44) | (b1 >> (64 - 44))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 9) | (b7 >> (64 - 9))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 54) | (b5 >> (64 - 54))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 56) | (b3 >> (64 - 56))) ^ b4;
+
+ b1 += k5;
+ b0 += b1 + k4;
+ b1 = ((b1 << 39) | (b1 >> (64 - 39))) ^ b0;
+
+ b3 += k7;
+ b2 += b3 + k6;
+ b3 = ((b3 << 30) | (b3 >> (64 - 30))) ^ b2;
+
+ b5 += k0 + t1;
+ b4 += b5 + k8;
+ b5 = ((b5 << 34) | (b5 >> (64 - 34))) ^ b4;
+
+ b7 += k2 + 13;
+ b6 += b7 + k1 + t2;
+ b7 = ((b7 << 24) | (b7 >> (64 - 24))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 50) | (b7 >> (64 - 50))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 10) | (b5 >> (64 - 10))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 17) | (b3 >> (64 - 17))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 29) | (b3 >> (64 - 29))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 39) | (b5 >> (64 - 39))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 43) | (b7 >> (64 - 43))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 8) | (b1 >> (64 - 8))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 35) | (b7 >> (64 - 35))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 56) | (b5 >> (64 - 56))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b4;
+
+ b1 += k6;
+ b0 += b1 + k5;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b0;
+
+ b3 += k8;
+ b2 += b3 + k7;
+ b3 = ((b3 << 36) | (b3 >> (64 - 36))) ^ b2;
+
+ b5 += k1 + t2;
+ b4 += b5 + k0;
+ b5 = ((b5 << 19) | (b5 >> (64 - 19))) ^ b4;
+
+ b7 += k3 + 14;
+ b6 += b7 + k2 + t0;
+ b7 = ((b7 << 37) | (b7 >> (64 - 37))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 33) | (b1 >> (64 - 33))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 27) | (b7 >> (64 - 27))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 14) | (b5 >> (64 - 14))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 42) | (b3 >> (64 - 42))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 17) | (b1 >> (64 - 17))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 49) | (b3 >> (64 - 49))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 36) | (b5 >> (64 - 36))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 39) | (b7 >> (64 - 39))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 44) | (b1 >> (64 - 44))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 9) | (b7 >> (64 - 9))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 54) | (b5 >> (64 - 54))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 56) | (b3 >> (64 - 56))) ^ b4;
+
+ b1 += k7;
+ b0 += b1 + k6;
+ b1 = ((b1 << 39) | (b1 >> (64 - 39))) ^ b0;
+
+ b3 += k0;
+ b2 += b3 + k8;
+ b3 = ((b3 << 30) | (b3 >> (64 - 30))) ^ b2;
+
+ b5 += k2 + t0;
+ b4 += b5 + k1;
+ b5 = ((b5 << 34) | (b5 >> (64 - 34))) ^ b4;
+
+ b7 += k4 + 15;
+ b6 += b7 + k3 + t1;
+ b7 = ((b7 << 24) | (b7 >> (64 - 24))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 50) | (b7 >> (64 - 50))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 10) | (b5 >> (64 - 10))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 17) | (b3 >> (64 - 17))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 29) | (b3 >> (64 - 29))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 39) | (b5 >> (64 - 39))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 43) | (b7 >> (64 - 43))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 8) | (b1 >> (64 - 8))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 35) | (b7 >> (64 - 35))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 56) | (b5 >> (64 - 56))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b4;
+
+ b1 += k8;
+ b0 += b1 + k7;
+ b1 = ((b1 << 46) | (b1 >> (64 - 46))) ^ b0;
+
+ b3 += k1;
+ b2 += b3 + k0;
+ b3 = ((b3 << 36) | (b3 >> (64 - 36))) ^ b2;
+
+ b5 += k3 + t1;
+ b4 += b5 + k2;
+ b5 = ((b5 << 19) | (b5 >> (64 - 19))) ^ b4;
+
+ b7 += k5 + 16;
+ b6 += b7 + k4 + t2;
+ b7 = ((b7 << 37) | (b7 >> (64 - 37))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 33) | (b1 >> (64 - 33))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 27) | (b7 >> (64 - 27))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 14) | (b5 >> (64 - 14))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 42) | (b3 >> (64 - 42))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 17) | (b1 >> (64 - 17))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 49) | (b3 >> (64 - 49))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 36) | (b5 >> (64 - 36))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 39) | (b7 >> (64 - 39))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 44) | (b1 >> (64 - 44))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 9) | (b7 >> (64 - 9))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 54) | (b5 >> (64 - 54))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 56) | (b3 >> (64 - 56))) ^ b4;
+
+ b1 += k0;
+ b0 += b1 + k8;
+ b1 = ((b1 << 39) | (b1 >> (64 - 39))) ^ b0;
+
+ b3 += k2;
+ b2 += b3 + k1;
+ b3 = ((b3 << 30) | (b3 >> (64 - 30))) ^ b2;
+
+ b5 += k4 + t2;
+ b4 += b5 + k3;
+ b5 = ((b5 << 34) | (b5 >> (64 - 34))) ^ b4;
+
+ b7 += k6 + 17;
+ b6 += b7 + k5 + t0;
+ b7 = ((b7 << 24) | (b7 >> (64 - 24))) ^ b6;
+
+ b2 += b1;
+ b1 = ((b1 << 13) | (b1 >> (64 - 13))) ^ b2;
+
+ b4 += b7;
+ b7 = ((b7 << 50) | (b7 >> (64 - 50))) ^ b4;
+
+ b6 += b5;
+ b5 = ((b5 << 10) | (b5 >> (64 - 10))) ^ b6;
+
+ b0 += b3;
+ b3 = ((b3 << 17) | (b3 >> (64 - 17))) ^ b0;
+
+ b4 += b1;
+ b1 = ((b1 << 25) | (b1 >> (64 - 25))) ^ b4;
+
+ b6 += b3;
+ b3 = ((b3 << 29) | (b3 >> (64 - 29))) ^ b6;
+
+ b0 += b5;
+ b5 = ((b5 << 39) | (b5 >> (64 - 39))) ^ b0;
+
+ b2 += b7;
+ b7 = ((b7 << 43) | (b7 >> (64 - 43))) ^ b2;
+
+ b6 += b1;
+ b1 = ((b1 << 8) | (b1 >> (64 - 8))) ^ b6;
+
+ b0 += b7;
+ b7 = ((b7 << 35) | (b7 >> (64 - 35))) ^ b0;
+
+ b2 += b5;
+ b5 = ((b5 << 56) | (b5 >> (64 - 56))) ^ b2;
+
+ b4 += b3;
+ b3 = ((b3 << 22) | (b3 >> (64 - 22))) ^ b4;
+
+ output[0] = b0 + k0;
+ output[1] = b1 + k1;
+ output[2] = b2 + k2;
+ output[3] = b3 + k3;
+ output[4] = b4 + k4;
+ output[5] = b5 + k5 + t0;
+ output[6] = b6 + k6 + t1;
+ output[7] = b7 + k7 + 18;
+}
+
+void threefishDecrypt512(struct threefish_key *keyCtx, u64 *input, u64 *output)
+{
+ u64 b0 = input[0], b1 = input[1],
+ b2 = input[2], b3 = input[3],
+ b4 = input[4], b5 = input[5],
+ b6 = input[6], b7 = input[7];
+ u64 k0 = keyCtx->key[0], k1 = keyCtx->key[1],
+ k2 = keyCtx->key[2], k3 = keyCtx->key[3],
+ k4 = keyCtx->key[4], k5 = keyCtx->key[5],
+ k6 = keyCtx->key[6], k7 = keyCtx->key[7],
+ k8 = keyCtx->key[8];
+ u64 t0 = keyCtx->tweak[0], t1 = keyCtx->tweak[1],
+ t2 = keyCtx->tweak[2];
+
+ u64 tmp;
+
+ b0 -= k0;
+ b1 -= k1;
+ b2 -= k2;
+ b3 -= k3;
+ b4 -= k4;
+ b5 -= k5 + t0;
+ b6 -= k6 + t1;
+ b7 -= k7 + 18;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 56) | (tmp << (64 - 56));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 35) | (tmp << (64 - 35));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 8) | (tmp << (64 - 8));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 43) | (tmp << (64 - 43));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 29) | (tmp << (64 - 29));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 17) | (tmp << (64 - 17));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 50) | (tmp << (64 - 50));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 24) | (tmp << (64 - 24));
+ b6 -= b7 + k5 + t0;
+ b7 -= k6 + 17;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 34) | (tmp << (64 - 34));
+ b4 -= b5 + k3;
+ b5 -= k4 + t2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 30) | (tmp << (64 - 30));
+ b2 -= b3 + k1;
+ b3 -= k2;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b1 + k8;
+ b1 -= k0;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 56) | (tmp << (64 - 56));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 54) | (tmp << (64 - 54));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 44) | (tmp << (64 - 44));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 39) | (tmp << (64 - 39));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 36) | (tmp << (64 - 36));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 49) | (tmp << (64 - 49));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 17) | (tmp << (64 - 17));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 42) | (tmp << (64 - 42));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 14) | (tmp << (64 - 14));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 27) | (tmp << (64 - 27));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 37) | (tmp << (64 - 37));
+ b6 -= b7 + k4 + t2;
+ b7 -= k5 + 16;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 19) | (tmp << (64 - 19));
+ b4 -= b5 + k2;
+ b5 -= k3 + t1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 36) | (tmp << (64 - 36));
+ b2 -= b3 + k0;
+ b3 -= k1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b1 + k7;
+ b1 -= k8;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 56) | (tmp << (64 - 56));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 35) | (tmp << (64 - 35));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 8) | (tmp << (64 - 8));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 43) | (tmp << (64 - 43));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 29) | (tmp << (64 - 29));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 17) | (tmp << (64 - 17));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 50) | (tmp << (64 - 50));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 24) | (tmp << (64 - 24));
+ b6 -= b7 + k3 + t1;
+ b7 -= k4 + 15;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 34) | (tmp << (64 - 34));
+ b4 -= b5 + k1;
+ b5 -= k2 + t0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 30) | (tmp << (64 - 30));
+ b2 -= b3 + k8;
+ b3 -= k0;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b1 + k6;
+ b1 -= k7;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 56) | (tmp << (64 - 56));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 54) | (tmp << (64 - 54));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 44) | (tmp << (64 - 44));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 39) | (tmp << (64 - 39));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 36) | (tmp << (64 - 36));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 49) | (tmp << (64 - 49));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 17) | (tmp << (64 - 17));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 42) | (tmp << (64 - 42));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 14) | (tmp << (64 - 14));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 27) | (tmp << (64 - 27));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 37) | (tmp << (64 - 37));
+ b6 -= b7 + k2 + t0;
+ b7 -= k3 + 14;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 19) | (tmp << (64 - 19));
+ b4 -= b5 + k0;
+ b5 -= k1 + t2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 36) | (tmp << (64 - 36));
+ b2 -= b3 + k7;
+ b3 -= k8;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b1 + k5;
+ b1 -= k6;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 56) | (tmp << (64 - 56));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 35) | (tmp << (64 - 35));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 8) | (tmp << (64 - 8));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 43) | (tmp << (64 - 43));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 29) | (tmp << (64 - 29));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 17) | (tmp << (64 - 17));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 50) | (tmp << (64 - 50));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 24) | (tmp << (64 - 24));
+ b6 -= b7 + k1 + t2;
+ b7 -= k2 + 13;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 34) | (tmp << (64 - 34));
+ b4 -= b5 + k8;
+ b5 -= k0 + t1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 30) | (tmp << (64 - 30));
+ b2 -= b3 + k6;
+ b3 -= k7;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b1 + k4;
+ b1 -= k5;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 56) | (tmp << (64 - 56));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 54) | (tmp << (64 - 54));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 44) | (tmp << (64 - 44));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 39) | (tmp << (64 - 39));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 36) | (tmp << (64 - 36));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 49) | (tmp << (64 - 49));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 17) | (tmp << (64 - 17));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 42) | (tmp << (64 - 42));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 14) | (tmp << (64 - 14));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 27) | (tmp << (64 - 27));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 37) | (tmp << (64 - 37));
+ b6 -= b7 + k0 + t1;
+ b7 -= k1 + 12;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 19) | (tmp << (64 - 19));
+ b4 -= b5 + k7;
+ b5 -= k8 + t0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 36) | (tmp << (64 - 36));
+ b2 -= b3 + k5;
+ b3 -= k6;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b1 + k3;
+ b1 -= k4;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 56) | (tmp << (64 - 56));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 35) | (tmp << (64 - 35));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 8) | (tmp << (64 - 8));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 43) | (tmp << (64 - 43));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 29) | (tmp << (64 - 29));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 17) | (tmp << (64 - 17));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 50) | (tmp << (64 - 50));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 24) | (tmp << (64 - 24));
+ b6 -= b7 + k8 + t0;
+ b7 -= k0 + 11;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 34) | (tmp << (64 - 34));
+ b4 -= b5 + k6;
+ b5 -= k7 + t2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 30) | (tmp << (64 - 30));
+ b2 -= b3 + k4;
+ b3 -= k5;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b1 + k2;
+ b1 -= k3;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 56) | (tmp << (64 - 56));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 54) | (tmp << (64 - 54));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 44) | (tmp << (64 - 44));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 39) | (tmp << (64 - 39));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 36) | (tmp << (64 - 36));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 49) | (tmp << (64 - 49));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 17) | (tmp << (64 - 17));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 42) | (tmp << (64 - 42));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 14) | (tmp << (64 - 14));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 27) | (tmp << (64 - 27));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 37) | (tmp << (64 - 37));
+ b6 -= b7 + k7 + t2;
+ b7 -= k8 + 10;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 19) | (tmp << (64 - 19));
+ b4 -= b5 + k5;
+ b5 -= k6 + t1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 36) | (tmp << (64 - 36));
+ b2 -= b3 + k3;
+ b3 -= k4;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b1 + k1;
+ b1 -= k2;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 56) | (tmp << (64 - 56));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 35) | (tmp << (64 - 35));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 8) | (tmp << (64 - 8));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 43) | (tmp << (64 - 43));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 29) | (tmp << (64 - 29));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 17) | (tmp << (64 - 17));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 50) | (tmp << (64 - 50));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 24) | (tmp << (64 - 24));
+ b6 -= b7 + k6 + t1;
+ b7 -= k7 + 9;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 34) | (tmp << (64 - 34));
+ b4 -= b5 + k4;
+ b5 -= k5 + t0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 30) | (tmp << (64 - 30));
+ b2 -= b3 + k2;
+ b3 -= k3;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b1 + k0;
+ b1 -= k1;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 56) | (tmp << (64 - 56));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 54) | (tmp << (64 - 54));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 44) | (tmp << (64 - 44));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 39) | (tmp << (64 - 39));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 36) | (tmp << (64 - 36));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 49) | (tmp << (64 - 49));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 17) | (tmp << (64 - 17));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 42) | (tmp << (64 - 42));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 14) | (tmp << (64 - 14));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 27) | (tmp << (64 - 27));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 37) | (tmp << (64 - 37));
+ b6 -= b7 + k5 + t0;
+ b7 -= k6 + 8;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 19) | (tmp << (64 - 19));
+ b4 -= b5 + k3;
+ b5 -= k4 + t2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 36) | (tmp << (64 - 36));
+ b2 -= b3 + k1;
+ b3 -= k2;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b1 + k8;
+ b1 -= k0;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 56) | (tmp << (64 - 56));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 35) | (tmp << (64 - 35));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 8) | (tmp << (64 - 8));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 43) | (tmp << (64 - 43));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 29) | (tmp << (64 - 29));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 17) | (tmp << (64 - 17));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 50) | (tmp << (64 - 50));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 24) | (tmp << (64 - 24));
+ b6 -= b7 + k4 + t2;
+ b7 -= k5 + 7;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 34) | (tmp << (64 - 34));
+ b4 -= b5 + k2;
+ b5 -= k3 + t1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 30) | (tmp << (64 - 30));
+ b2 -= b3 + k0;
+ b3 -= k1;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b1 + k7;
+ b1 -= k8;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 56) | (tmp << (64 - 56));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 54) | (tmp << (64 - 54));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 44) | (tmp << (64 - 44));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 39) | (tmp << (64 - 39));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 36) | (tmp << (64 - 36));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 49) | (tmp << (64 - 49));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 17) | (tmp << (64 - 17));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 42) | (tmp << (64 - 42));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 14) | (tmp << (64 - 14));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 27) | (tmp << (64 - 27));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 37) | (tmp << (64 - 37));
+ b6 -= b7 + k3 + t1;
+ b7 -= k4 + 6;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 19) | (tmp << (64 - 19));
+ b4 -= b5 + k1;
+ b5 -= k2 + t0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 36) | (tmp << (64 - 36));
+ b2 -= b3 + k8;
+ b3 -= k0;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b1 + k6;
+ b1 -= k7;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 56) | (tmp << (64 - 56));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 35) | (tmp << (64 - 35));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 8) | (tmp << (64 - 8));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 43) | (tmp << (64 - 43));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 29) | (tmp << (64 - 29));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 17) | (tmp << (64 - 17));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 50) | (tmp << (64 - 50));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 24) | (tmp << (64 - 24));
+ b6 -= b7 + k2 + t0;
+ b7 -= k3 + 5;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 34) | (tmp << (64 - 34));
+ b4 -= b5 + k0;
+ b5 -= k1 + t2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 30) | (tmp << (64 - 30));
+ b2 -= b3 + k7;
+ b3 -= k8;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b1 + k5;
+ b1 -= k6;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 56) | (tmp << (64 - 56));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 54) | (tmp << (64 - 54));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 44) | (tmp << (64 - 44));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 39) | (tmp << (64 - 39));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 36) | (tmp << (64 - 36));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 49) | (tmp << (64 - 49));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 17) | (tmp << (64 - 17));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 42) | (tmp << (64 - 42));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 14) | (tmp << (64 - 14));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 27) | (tmp << (64 - 27));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 37) | (tmp << (64 - 37));
+ b6 -= b7 + k1 + t2;
+ b7 -= k2 + 4;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 19) | (tmp << (64 - 19));
+ b4 -= b5 + k8;
+ b5 -= k0 + t1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 36) | (tmp << (64 - 36));
+ b2 -= b3 + k6;
+ b3 -= k7;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b1 + k4;
+ b1 -= k5;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 56) | (tmp << (64 - 56));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 35) | (tmp << (64 - 35));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 8) | (tmp << (64 - 8));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 43) | (tmp << (64 - 43));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 29) | (tmp << (64 - 29));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 17) | (tmp << (64 - 17));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 50) | (tmp << (64 - 50));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 24) | (tmp << (64 - 24));
+ b6 -= b7 + k0 + t1;
+ b7 -= k1 + 3;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 34) | (tmp << (64 - 34));
+ b4 -= b5 + k7;
+ b5 -= k8 + t0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 30) | (tmp << (64 - 30));
+ b2 -= b3 + k5;
+ b3 -= k6;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b1 + k3;
+ b1 -= k4;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 56) | (tmp << (64 - 56));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 54) | (tmp << (64 - 54));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 44) | (tmp << (64 - 44));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 39) | (tmp << (64 - 39));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 36) | (tmp << (64 - 36));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 49) | (tmp << (64 - 49));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 17) | (tmp << (64 - 17));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 42) | (tmp << (64 - 42));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 14) | (tmp << (64 - 14));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 27) | (tmp << (64 - 27));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 37) | (tmp << (64 - 37));
+ b6 -= b7 + k8 + t0;
+ b7 -= k0 + 2;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 19) | (tmp << (64 - 19));
+ b4 -= b5 + k6;
+ b5 -= k7 + t2;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 36) | (tmp << (64 - 36));
+ b2 -= b3 + k4;
+ b3 -= k5;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b1 + k2;
+ b1 -= k3;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 22) | (tmp << (64 - 22));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 56) | (tmp << (64 - 56));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 35) | (tmp << (64 - 35));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 8) | (tmp << (64 - 8));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 43) | (tmp << (64 - 43));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 29) | (tmp << (64 - 29));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 25) | (tmp << (64 - 25));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 17) | (tmp << (64 - 17));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 10) | (tmp << (64 - 10));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 50) | (tmp << (64 - 50));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 13) | (tmp << (64 - 13));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 24) | (tmp << (64 - 24));
+ b6 -= b7 + k7 + t2;
+ b7 -= k8 + 1;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 34) | (tmp << (64 - 34));
+ b4 -= b5 + k5;
+ b5 -= k6 + t1;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 30) | (tmp << (64 - 30));
+ b2 -= b3 + k3;
+ b3 -= k4;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 39) | (tmp << (64 - 39));
+ b0 -= b1 + k1;
+ b1 -= k2;
+
+ tmp = b3 ^ b4;
+ b3 = (tmp >> 56) | (tmp << (64 - 56));
+ b4 -= b3;
+
+ tmp = b5 ^ b2;
+ b5 = (tmp >> 54) | (tmp << (64 - 54));
+ b2 -= b5;
+
+ tmp = b7 ^ b0;
+ b7 = (tmp >> 9) | (tmp << (64 - 9));
+ b0 -= b7;
+
+ tmp = b1 ^ b6;
+ b1 = (tmp >> 44) | (tmp << (64 - 44));
+ b6 -= b1;
+
+ tmp = b7 ^ b2;
+ b7 = (tmp >> 39) | (tmp << (64 - 39));
+ b2 -= b7;
+
+ tmp = b5 ^ b0;
+ b5 = (tmp >> 36) | (tmp << (64 - 36));
+ b0 -= b5;
+
+ tmp = b3 ^ b6;
+ b3 = (tmp >> 49) | (tmp << (64 - 49));
+ b6 -= b3;
+
+ tmp = b1 ^ b4;
+ b1 = (tmp >> 17) | (tmp << (64 - 17));
+ b4 -= b1;
+
+ tmp = b3 ^ b0;
+ b3 = (tmp >> 42) | (tmp << (64 - 42));
+ b0 -= b3;
+
+ tmp = b5 ^ b6;
+ b5 = (tmp >> 14) | (tmp << (64 - 14));
+ b6 -= b5;
+
+ tmp = b7 ^ b4;
+ b7 = (tmp >> 27) | (tmp << (64 - 27));
+ b4 -= b7;
+
+ tmp = b1 ^ b2;
+ b1 = (tmp >> 33) | (tmp << (64 - 33));
+ b2 -= b1;
+
+ tmp = b7 ^ b6;
+ b7 = (tmp >> 37) | (tmp << (64 - 37));
+ b6 -= b7 + k6 + t1;
+ b7 -= k7;
+
+ tmp = b5 ^ b4;
+ b5 = (tmp >> 19) | (tmp << (64 - 19));
+ b4 -= b5 + k4;
+ b5 -= k5 + t0;
+
+ tmp = b3 ^ b2;
+ b3 = (tmp >> 36) | (tmp << (64 - 36));
+ b2 -= b3 + k2;
+ b3 -= k3;
+
+ tmp = b1 ^ b0;
+ b1 = (tmp >> 46) | (tmp << (64 - 46));
+ b0 -= b1 + k0;
+ b1 -= k1;
+
+ output[0] = b0;
+ output[1] = b1;
+ output[2] = b2;
+ output[3] = b3;
+
+ output[7] = b7;
+ output[6] = b6;
+ output[5] = b5;
+ output[4] = b4;
+}
--- /dev/null
+
+
+#include <linux/string.h>
+#include <threefishApi.h>
+
+void threefishSetKey(struct threefish_key *keyCtx,
+ enum threefish_size stateSize,
+ u64 *keyData, u64 *tweak)
+{
+ int keyWords = stateSize / 64;
+ int i;
+ u64 parity = KeyScheduleConst;
+
+ keyCtx->tweak[0] = tweak[0];
+ keyCtx->tweak[1] = tweak[1];
+ keyCtx->tweak[2] = tweak[0] ^ tweak[1];
+
+ for (i = 0; i < keyWords; i++) {
+ keyCtx->key[i] = keyData[i];
+ parity ^= keyData[i];
+ }
+ keyCtx->key[i] = parity;
+ keyCtx->stateSize = stateSize;
+}
+
+void threefishEncryptBlockBytes(struct threefish_key *keyCtx, u8 *in,
+ u8 *out)
+{
+ u64 plain[SKEIN_MAX_STATE_WORDS]; /* max number of words*/
+ u64 cipher[SKEIN_MAX_STATE_WORDS];
+
+ Skein_Get64_LSB_First(plain, in, keyCtx->stateSize / 64);
+ threefishEncryptBlockWords(keyCtx, plain, cipher);
+ Skein_Put64_LSB_First(out, cipher, keyCtx->stateSize / 8);
+}
+
+void threefishEncryptBlockWords(struct threefish_key *keyCtx, u64 *in,
+ u64 *out)
+{
+ switch (keyCtx->stateSize) {
+ case Threefish256:
+ threefishEncrypt256(keyCtx, in, out);
+ break;
+ case Threefish512:
+ threefishEncrypt512(keyCtx, in, out);
+ break;
+ case Threefish1024:
+ threefishEncrypt1024(keyCtx, in, out);
+ break;
+ }
+}
+
+void threefishDecryptBlockBytes(struct threefish_key *keyCtx, u8 *in,
+ u8 *out)
+{
+ u64 plain[SKEIN_MAX_STATE_WORDS]; /* max number of words*/
+ u64 cipher[SKEIN_MAX_STATE_WORDS];
+
+ Skein_Get64_LSB_First(cipher, in, keyCtx->stateSize / 64);
+ threefishDecryptBlockWords(keyCtx, cipher, plain);
+ Skein_Put64_LSB_First(out, plain, keyCtx->stateSize / 8);
+}
+
+void threefishDecryptBlockWords(struct threefish_key *keyCtx, u64 *in,
+ u64 *out)
+{
+ switch (keyCtx->stateSize) {
+ case Threefish256:
+ threefishDecrypt256(keyCtx, in, out);
+ break;
+ case Threefish512:
+ threefishDecrypt512(keyCtx, in, out);
+ break;
+ case Threefish1024:
+ threefishDecrypt1024(keyCtx, in, out);
+ break;
+ }
+}
+
spin_lock_irqsave(&adapter->handle_lock.lock,
adapter->handle_lock.flags);
pslic_handle = adapter->pfree_slic_handles;
- if (pslic_handle)
- adapter->pfree_slic_handles = pslic_handle->next;
+ adapter->pfree_slic_handles = pslic_handle->next;
spin_unlock_irqrestore(&adapter->handle_lock.lock,
adapter->handle_lock.flags);
pslic_handle->type = SLIC_HANDLE_CMD;
if (kstrtol(cp, 10, &value) == 0)
ret = spk_set_num_var(value, param, len);
else
- pr_warn("overflow or parsing error has occured");
+ pr_warn("overflow or parsing error has occurred");
if (ret == -ERANGE) {
var_data = param->data;
pr_warn("value for %s out of range, expect %d to %d\n",
{
static u_char goto_buf[8];
static int num;
- int maxlen, go_pos;
+ int maxlen;
char *cp;
+
if (type == KT_SPKUP && ch == SPEAKUP_GOTO)
goto do_goto;
if (type == KT_LATIN && ch == '\n')
spk_special_handler = NULL;
return 1;
}
- go_pos = kstrtol(goto_buf, 10, (long *)&cp);
- goto_pos = (u_long) go_pos;
+
+ goto_pos = simple_strtoul(goto_buf, &cp, 10);
+
if (*cp == 'x') {
if (*goto_buf < '0')
goto_pos += spk_x;
- else
+ else if (goto_pos > 0)
goto_pos--;
- if (goto_pos < 0)
- goto_pos = 0;
+
if (goto_pos >= vc->vc_cols)
goto_pos = vc->vc_cols - 1;
goto_x = 1;
} else {
if (*goto_buf < '0')
goto_pos += spk_y;
- else
+ else if (goto_pos > 0)
goto_pos--;
- if (goto_pos < 0)
- goto_pos = 0;
+
if (goto_pos >= vc->vc_rows)
goto_pos = vc->vc_rows - 1;
goto_x = 0;
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
*/
/* define the following to prevent include nesting in kernel header
- * files of similar abreviated content
+ * files of similar abbreviated content
*/
#define __SUPERVISOR_CHANNEL_H__
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
*IsChannelInitialized: 1 iff SignalInit was called for this channel; otherwise
* 0, and assume the channel is not ready for use yet.
*
- * Reserved: Padding to allign the fields in this structure.
+ * Reserved: Padding to align the fields in this structure.
*
*SubsystemSeverityFilter: Level of severity on a subsystem basis that controls
* whether events are logged. Any event's severity for a
-/* Copyright © 2010 - 2013 UNISYS CORPORATION */
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION */
/* All rights reserved. */
#ifndef __IOCHANNEL_H__
#define __IOCHANNEL_H__
/* uisnic -> virtnic */
NET_MACADDR, /* indicates the client has requested to update
* its MAC addr */
- NET_MACADDR_ACK, /* Mac addres */
+ NET_MACADDR_ACK, /* MAC address */
} NET_TYPES;
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* controlvmcompletionstatus.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
#define _COMMONTYPES_H_
/* define the following to prevent include nesting in kernel header files of
- * similar abreviated content */
+ * similar abbreviated content */
#define _SUPERVISOR_COMMONTYPES_H_
#ifdef __KERNEL__
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
#define __GUESTLINUXDEBUG_H__
/*
-* This file contains supporting interface for "vmcallinterface.h", particuarly
+* This file contains supporting interface for "vmcallinterface.h", particularly
* regarding adding additional structure and functionality to linux
* ISSUE_IO_VMCALL_POSTCODE_SEVERITY */
* 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 occured on, or where the last driver
+ * exactly what line an error occurred on, or where the last driver
* entered/exited from.
*/
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* periodic_work.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* procobjecttree.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* sparstop.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* timskmod.h
*
- * Copyright � 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* timskmodutils.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* uisqueue.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* uisthread.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* uisutils.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* uniklog.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* uislib.c
*
- * Copyright � 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
cmd.add_vbus.busTypeGuid = msg->cmd.createBus.busDataTypeGuid;
cmd.add_vbus.busInstGuid = msg->cmd.createBus.busInstGuid;
if (!VirtControlChanFunc) {
- kfree(bus);
LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered.");
POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo,
POSTCODE_SEVERITY_ERR);
+ kfree(bus);
return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
}
if (!VirtControlChanFunc(&cmd)) {
- kfree(bus);
LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error.");
POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo,
POSTCODE_SEVERITY_ERR);
+ kfree(bus);
return
CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
}
/* uisqueue.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* uisthread.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* uisutils.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* virthba.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
static int virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
void (*virthba_cmnd_done)(struct scsi_cmnd *));
+static const struct x86_cpu_id unisys_spar_ids[] = {
+ { X86_VENDOR_INTEL, 6, 62, X86_FEATURE_ANY },
+ {}
+};
+
+/* Autoload */
+MODULE_DEVICE_TABLE(x86cpu, unisys_spar_ids);
+
#ifdef DEF_SCSI_QCMD
DEF_SCSI_QCMD(virthba_queue_command)
#else
virthba_slave_alloc(struct scsi_device *scsidev)
{
/* this called by the midlayer before scan for new devices -
- * LLD can alloc any struc & do init if needed.
+ * LLD can alloc any struct & do init if needed.
*/
struct virtdisk_info *vdisk;
struct virtdisk_info *tmpvdisk;
virthbainfo = VirtHbasOpen[i].virthbainfo;
length += sprintf(vbuf + length, "CHANSOCK is not defined.\n");
- length += sprintf(vbuf + length, "MaxBuffLen:%d\n", MaxBuffLen);
+ length += sprintf(vbuf + length, "MaxBuffLen:%u\n", MaxBuffLen);
length += sprintf(vbuf + length, "\nvirthba result queue poll wait:%d usecs.\n",
rsltq_wait_usecs);
virtpcidev->deviceNo);
if (!virthbainfo->serverdown) {
- DBGINF("Server up message recieved while server is already up.\n");
+ DBGINF("Server up message received while server is already up.\n");
return 1;
}
if (virthbainfo->serverchangingstate) {
/* virthba.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* virtpci.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* virtpci.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* globals.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* visorchannel.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* visorchannel_funcs.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* visorchannel_main.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* controlvm.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* controlvm_direct.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* file.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* file.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* globals.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* parser.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* parser.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* testing.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* visorchipset.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
static inline void delbusdevices(struct list_head *list, U32 busNo)
{
- VISORCHIPSET_DEVICE_INFO *p;
+ VISORCHIPSET_DEVICE_INFO *p, *tmp;
- list_for_each_entry(p, list, entry) {
+ list_for_each_entry_safe(p, tmp, list, entry) {
if (p->busNo == busNo) {
list_del(&p->entry);
kfree(p);
/* visorchipset_main.c
*
- * Copyright � 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
static void
cleanup_controlvm_structures(void)
{
- VISORCHIPSET_BUS_INFO *bi;
- VISORCHIPSET_DEVICE_INFO *di;
+ VISORCHIPSET_BUS_INFO *bi, *tmp_bi;
+ VISORCHIPSET_DEVICE_INFO *di, *tmp_di;
- list_for_each_entry(bi, &BusInfoList, entry) {
+ list_for_each_entry_safe(bi, tmp_bi, &BusInfoList, entry) {
busInfo_clear(bi);
list_del(&bi->entry);
kfree(bi);
}
- list_for_each_entry(di, &DevInfoList, entry) {
+ list_for_each_entry_safe(di, tmp_di, &DevInfoList, entry) {
devInfo_clear(di);
list_del(&di->entry);
kfree(di);
/* visorchipset_umode.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* charqueue.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* charqueue.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
-/* Copyright © 2010 - 2013 UNISYS CORPORATION
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* easyproc.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* memregion.h
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* memregion_direct.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* periodic_work.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* procobjecttree.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
/* timskmodutils.c
*
- * Copyright © 2010 - 2013 UNISYS CORPORATION
+ * Copyright (C) 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
struct udev_list_entry *devices, *dev_list_entry;
struct udev_device *dev;
const char *path;
+ const char *driver;
enumerate = udev_enumerate_new(udev_context);
udev_enumerate_add_match_subsystem(enumerate, "usb");
udev_list_entry_foreach(dev_list_entry, devices) {
path = udev_list_entry_get_name(dev_list_entry);
dev = udev_device_new_from_syspath(udev_context, path);
+ if (dev == NULL)
+ continue;
/* Check whether device uses usbip-host driver. */
- if (!strcmp(udev_device_get_driver(dev),
- USBIP_HOST_DRV_NAME)) {
+ driver = udev_device_get_driver(dev);
+ if (driver != NULL && !strcmp(driver, USBIP_HOST_DRV_NAME)) {
edev = usbip_exported_device_new(path);
if (!edev) {
dbg("usbip_exported_device_new failed");
* @devid: unique device identifier in a remote host
* @speed: usb device speed in a remote host
*/
- if (sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed) != 1)
+ if (sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed) != 4)
return -EINVAL;
usbip_dbg_vhci_sysfs("rhport(%u) sockfd(%u) devid(%u) speed(%u)\n",
static int vme_user_probe(struct vme_dev *vdev)
{
int i, err;
- char name[12];
+ char *name;
/* Save pointer to the bridge device */
if (vme_user_bridge != NULL) {
image[i].kern_buf = kmalloc(image[i].size_buf, GFP_KERNEL);
if (image[i].kern_buf == NULL) {
err = -ENOMEM;
- goto err_master_buf;
+ vme_master_free(image[i].resource);
+ goto err_master;
}
}
/* Add sysfs Entries */
for (i = 0; i < VME_DEVS; i++) {
int num;
+
switch (type[i]) {
case MASTER_MINOR:
- sprintf(name, "bus/vme/m%%d");
+ name = "bus/vme/m%d";
break;
case CONTROL_MINOR:
- sprintf(name, "bus/vme/ctl");
+ name = "bus/vme/ctl";
break;
case SLAVE_MINOR:
- sprintf(name, "bus/vme/s%%d");
+ name = "bus/vme/s%d";
break;
default:
err = -EINVAL;
return 0;
- /* Ensure counter set correcty to destroy all sysfs devices */
- i = VME_DEVS;
err_sysfs:
while (i > 0) {
i--;
/* Ensure counter set correcty to unalloc all master windows */
i = MASTER_MAX + 1;
-err_master_buf:
- for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++)
- kfree(image[i].kern_buf);
err_master:
while (i > MASTER_MINOR) {
i--;
+ kfree(image[i].kern_buf);
vme_master_free(image[i].resource);
}
* vUpdateIFS - Update slotTime,SIFS,DIFS, and EIFS
* CARDvUpdateBasicTopRate - Update BasicTopRate
* CARDbAddBasicRate - Add to BasicRateSet
- * CARDbSetBasicRate - Set Basic Tx Rate
* CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet
* CARDvSetLoopbackMode - Set Loopback mode
* CARDbSoftwareReset - Sortware reset NIC
pDevice->byTopCCKBasicRate = byTopCCK;
}
-/*
- * Description: Set NIC Tx Basic Rate
- *
- * Parameters:
- * In:
- * pDevice - The adapter to be set
- * wBasicRate - Basic Rate to be set
- * Out:
- * none
- *
- * Return Value: true if succeeded; false if failed.
- *
- */
bool CARDbAddBasicRate(void *pDeviceHandler, unsigned short wRateIdx)
{
PSDevice pDevice = (PSDevice) pDeviceHandler;
/*--------------------- Static Variables --------------------------*/
//static int msglevel =MSG_LEVEL_DEBUG;
static int msglevel = MSG_LEVEL_INFO;
-const unsigned char acbyIERate[MAX_RATE] =
+static const unsigned char acbyIERate[MAX_RATE] =
{0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
#define AUTORATE_TXOK_CNT 0x0400
/*--------------------- Export Types ------------------------------*/
-#define DBG_PRT(l, p, args...) { if (l <= msglevel) printk(p, ##args); }
-#define PRINT_K(p, args...) { if (PRIVATE_Message) printk(p, ##args); }
+#define DBG_PRT(l, p, args...) \
+do { \
+ if (l <= msglevel) \
+ printk(p, ##args); \
+} while (0)
+
+#define PRINT_K(p, args...) \
+do { \
+ if (PRIVATE_Message) \
+ printk(p, ##args); \
+} while (0)
//0:11A 1:11B 2:11G
typedef enum _VIA_BB_TYPE
result = -EINVAL;
break;
}
- pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), (int)GFP_ATOMIC);
+ pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)),
+ GFP_ATOMIC);
if (pList == NULL) {
result = -ENOMEM;
break;
result = -EINVAL;
break;
}
- pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC);
+ pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)),
+ GFP_ATOMIC);
if (pNodeList == NULL) {
result = -ENOMEM;
break;
size_t seq_len = 0, key_len = 0;
//
// int ii;
- u8 *buf;
- size_t blen;
u8 key_array[64];
int ret = 0;
PRINT_K("SIOCSIWENCODEEXT...... \n");
- blen = sizeof(*param);
- buf = kmalloc((int)blen, (int)GFP_KERNEL);
- if (buf == NULL)
+ param = kzalloc(sizeof(*param), GFP_KERNEL);
+ if (param == NULL)
return -ENOMEM;
- memset(buf, 0, blen);
- param = (struct viawget_wpa_param *)buf;
//recover alg_name
switch (ext->alg) {
*
*/
-int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel)
+int wpa_set_keys(PSDevice pDevice, void *ctx,
+ bool fcpfkernel) __must_hold(&pDevice->lock)
{
struct viawget_wpa_param *param = ctx;
PSMgmtObject pMgmt = pDevice->pMgmt;
unsigned char *ptempBSS;
- ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC);
+ ptempBSS = kmalloc(sizeof(KnownBSS), GFP_ATOMIC);
if (ptempBSS == NULL) {
printk(KERN_ERR "bubble sort kmalloc memory fail@@@\n");
count++;
}
- pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC);
+ pBuf = kcalloc(count, sizeof(struct viawget_scan_result), GFP_ATOMIC);
if (pBuf == NULL) {
ret = -ENOMEM;
ret = -EFAULT;
}
param->u.scan_results.scan_count = count;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count)
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count);
kfree(pBuf);
return ret;
p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer)
return -EINVAL;
- param = kmalloc((int)p->length, (int)GFP_KERNEL);
+ param = kmalloc((int)p->length, GFP_KERNEL);
if (param == NULL)
return -ENOMEM;
#include "device.h"
#include "80211hdr.h"
+#include "aes_ccmp.h"
/*
* SBOX Table
*
*/
+#include <linux/compiler.h>
#include "firmware.h"
#include "control.h"
#include "rndis.h"
#define FIRMWARE_CHUNK_SIZE 0x400
-int FIRMWAREbDownload(struct vnt_private *pDevice)
+int FIRMWAREbDownload(struct vnt_private *pDevice) __must_hold(&pDevice->lock)
{
struct device *dev = &pDevice->usb->dev;
const struct firmware *fw;
struct vnt_mic_hdr *mic_hdr)
{
u8 *pbyBuf = (u8 *)&fifo_head->adwTxKey[0];
- u32 *pdwIV = (u32 *)pbyIVHead;
- u32 *pdwExtIV = (u32 *)((u8 *)pbyIVHead + 4);
+ __le32 *pdwIV = (__le32 *)pbyIVHead;
+ __le32 *pdwExtIV = (__le32 *)((u8 *)pbyIVHead + 4);
struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyHdrBuf;
- u32 dwRevIVCounter;
+ __le32 rev_iv_counter;
/* Fill TXKEY */
if (pTransmitKey == NULL)
return;
- dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
- *pdwIV = pDevice->dwIVCounter;
+ rev_iv_counter = cpu_to_le32(pDevice->dwIVCounter);
+ *pdwIV = cpu_to_le32(pDevice->dwIVCounter);
pDevice->byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
switch (pTransmitKey->byCipherSuite) {
case KEY_CTL_WEP:
if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) {
- memcpy(pDevice->abyPRNG, (u8 *)&dwRevIVCounter, 3);
+ memcpy(pDevice->abyPRNG, (u8 *)&rev_iv_counter, 3);
memcpy(pDevice->abyPRNG + 3, pTransmitKey->abyKey,
pTransmitKey->uKeyLength);
} else {
- memcpy(pbyBuf, (u8 *)&dwRevIVCounter, 3);
+ memcpy(pbyBuf, (u8 *)&rev_iv_counter, 3);
memcpy(pbyBuf + 3, pTransmitKey->abyKey,
pTransmitKey->uKeyLength);
if (pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
- memcpy(pbyBuf+8, (u8 *)&dwRevIVCounter, 3);
+ memcpy(pbyBuf+8, (u8 *)&rev_iv_counter, 3);
memcpy(pbyBuf+11, pTransmitKey->abyKey,
pTransmitKey->uKeyLength);
}
memcpy(pDevice->abyPRNG, pbyBuf, 16);
}
/* Append IV after Mac Header */
- *pdwIV &= WEP_IV_MASK;
- *pdwIV |= (u32)pDevice->byKeyIndex << 30;
- *pdwIV = cpu_to_le32(*pdwIV);
+ *pdwIV &= cpu_to_le32(WEP_IV_MASK);
+ *pdwIV |= cpu_to_le32((u32)pDevice->byKeyIndex << 30);
pDevice->dwIVCounter++;
if (pDevice->dwIVCounter > WEP_IV_MASK)
*(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) &
0xc0) | 0x20);
- *pdwIV |= cpu_to_le16((u16)(pTransmitKey->wTSC15_0));
+ *pdwIV |= cpu_to_le32((u32)(pTransmitKey->wTSC15_0));
/* Append IV&ExtIV after Mac Header */
*pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
/* MICHDR2 */
memcpy(mic_hdr->addr3, pMACHeader->addr3, ETH_ALEN);
- mic_hdr->frame_control = cpu_to_le16(pMACHeader->frame_control
- & 0xc78f);
- mic_hdr->seq_ctrl = cpu_to_le16(pMACHeader->seq_ctrl & 0xf);
+ mic_hdr->frame_control = cpu_to_le16(
+ le16_to_cpu(pMACHeader->frame_control) & 0xc78f);
+ mic_hdr->seq_ctrl = cpu_to_le16(
+ le16_to_cpu(pMACHeader->seq_ctrl) & 0xf);
if (ieee80211_has_a4(pMACHeader->frame_control))
memcpy(mic_hdr->addr4, pMACHeader->addr4, ETH_ALEN);
__le16 duration)
{
rts->duration = duration;
- rts->frame_control = TYPE_CTL_RTS;
+ rts->frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
if (priv->op_mode == NL80211_IFTYPE_ADHOC ||
priv->op_mode == NL80211_IFTYPE_AP)
pDevice->tx_rate_fb1, bNeedAck, byFBOption);
/* Get CTS Frame body */
pBuf->data.duration = pBuf->duration_ba;
- pBuf->data.frame_control = TYPE_CTL_CTS;
+ pBuf->data.frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
+
memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
return vnt_rxtx_datahead_g_fb(pDevice, byPktType, wCurrentRate,
wCurrentRate, bNeedAck, byFBOption);
/*Get CTS Frame body*/
pBuf->data.duration = pBuf->duration_ba;
- pBuf->data.frame_control = TYPE_CTL_CTS;
+ pBuf->data.frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
+
memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
return vnt_rxtx_datahead_g(pDevice, byPktType, wCurrentRate,
u16 wFifoCtl;
u8 byFBOption = AUTO_FB_NONE;
- pFifoHead->wReserved = wCurrentRate;
+ pFifoHead->current_rate = cpu_to_le16(wCurrentRate);
wFifoCtl = pFifoHead->wFIFOCtl;
if (wFifoCtl & FIFOCTL_AUTO_FB_0)
pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
}
- pTxBufHead->wTimeStamp = DEFAULT_MSDU_LIFETIME_RES_64us;
+ pTxBufHead->time_stamp = cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
//Set FRAGCTL_MACHDCNT
cbMACHdLen = WLAN_HDR_ADDR3_LEN;
}
pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
- pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
+ pTxBufHead->time_stamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
if (is_multicast_ether_addr(pPacket->p80211Header->sA3.abyAddr1)) {
bNeedACK = false;
}
}
- pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
+ pTX_Buffer->tx_byte_count = cpu_to_le16((u16)(cbReqCount));
pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
pTX_Buffer->byType = 0x00;
cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize;
- pTX_Buffer->wTxByteCount = (u16)cbReqCount;
+ pTX_Buffer->tx_byte_count = cpu_to_le16((u16)cbReqCount);
pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
pTX_Buffer->byType = 0x01;
}
pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
- pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
+ pTxBufHead->time_stamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
if (is_multicast_ether_addr(p80211Header->sA3.abyAddr1)) {
bNeedACK = false;
}
}
- pTX_Buffer->wTxByteCount = cpu_to_le16((u16)(cbReqCount));
+ pTX_Buffer->tx_byte_count = cpu_to_le16((u16)(cbReqCount));
pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
pTX_Buffer->byType = 0x00;
}
pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
- pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
+ pTX_Buffer->tx_byte_count = cpu_to_le16((u16)BytesToWrite);
pContext->pPacket = skb;
pContext->type = CONTEXT_DATA_PACKET;
}
pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
- pTX_Buffer->wTxByteCount = (u16)BytesToWrite;
+ pTX_Buffer->tx_byte_count = cpu_to_le16((u16)BytesToWrite);
pContext->pPacket = NULL;
pContext->type = CONTEXT_DATA_PACKET;
struct vnt_tx_fifo_head {
u32 adwTxKey[4];
u16 wFIFOCtl;
- u16 wTimeStamp;
+ __le16 time_stamp;
u16 wFragCtl;
- u16 wReserved;
+ __le16 current_rate;
} __packed;
struct vnt_tx_buffer {
u8 byType;
u8 byPKTNO;
- u16 wTxByteCount;
+ __le16 tx_byte_count;
struct vnt_tx_fifo_head fifo_head;
union vnt_tx_head tx_head;
} __packed;
struct vnt_beacon_buffer {
u8 byType;
u8 byPKTNO;
- u16 wTxByteCount;
+ __le16 tx_byte_count;
struct vnt_tx_short_buf_head short_head;
struct ieee80211_hdr hdr;
} __packed;
#define TYPE_DATE_NULL 0x4800
#define TYPE_CTL_PSPOLL 0xa400
-#define TYPE_CTL_RTS 0xb400
-#define TYPE_CTL_CTS 0xc400
#define TYPE_CTL_ACK 0xd400
#else //if LITTLE_ENDIAN
#define TYPE_DATE_NULL 0x0048
#define TYPE_CTL_PSPOLL 0x00a4
-#define TYPE_CTL_RTS 0x00b4
-#define TYPE_CTL_CTS 0x00c4
#define TYPE_CTL_ACK 0x00d4
#endif //#ifdef __BIG_ENDIAN
#include "prism2sta.c"
#include "prism2fw.c"
-#define PRISM_USB_DEVICE(vid, pid, name) \
- USB_DEVICE(vid, pid), \
- .driver_info = (unsigned long) name
+#define PRISM_DEV(vid, pid, name) \
+ { USB_DEVICE(vid, pid), \
+ .driver_info = (unsigned long) name }
static struct usb_device_id usb_prism_tbl[] = {
- {PRISM_USB_DEVICE(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS")},
- {PRISM_USB_DEVICE(0x07aa, 0x0012, "Corega Wireless LAN USB Stick-11")},
- {PRISM_USB_DEVICE(0x09aa, 0x3642, "Prism2.x 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE
- (0x1668, 0x0408, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE
- (0x1668, 0x0421, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE
- (0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE
- (0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE
- (0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE
- (0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE
- (0x049f, 0x0033,
- "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
- {PRISM_USB_DEVICE
- (0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")},
- {PRISM_USB_DEVICE
- (0x08de, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
- {PRISM_USB_DEVICE
- (0x8086, 0x1111, "Intel PRO/Wireless 2011B LAN USB Adapter")},
- {PRISM_USB_DEVICE
- (0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
- {PRISM_USB_DEVICE
- (0x045e, 0x006e, "Microsoft MN510 Wireless USB Adapter")},
- {PRISM_USB_DEVICE(0x0967, 0x0204, "Acer Warplink USB Adapter")},
- {PRISM_USB_DEVICE
- (0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated")},
- {PRISM_USB_DEVICE
- (0x0cde, 0x0005, "Z-Com Xl735 Wireless 802.11b USB Adapter")},
- {PRISM_USB_DEVICE
- (0x413c, 0x8100, "Dell TrueMobile 1180 Wireless USB Adapter")},
- {PRISM_USB_DEVICE
- (0x0b3b, 0x1601, "ALLNET 0193 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE
- (0x0b3b, 0x1602, "ZyXEL ZyAIR B200 Wireless USB Adapter")},
- {PRISM_USB_DEVICE
- (0x0baf, 0x00eb, "USRobotics USR1120 Wireless USB Adapter")},
- {PRISM_USB_DEVICE
- (0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter")},
- {PRISM_USB_DEVICE
- (0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")},
- {PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")},
- {PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")},
- {PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")},
- {PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")},
- {PRISM_USB_DEVICE
- (0x2001, 0x3702, "DWL-120 Rev F Wireless USB Adapter")},
- {PRISM_USB_DEVICE(0x50c2, 0x4013, "Averatec USB WLAN Adapter")},
- {PRISM_USB_DEVICE(0x2c02, 0x14ea, "Planex GW-US11H WLAN USB Adapter")},
- {PRISM_USB_DEVICE(0x124a, 0x168b, "Airvast PRISM3 WLAN USB Adapter")},
- {PRISM_USB_DEVICE(0x083a, 0x3503, "T-Sinus 111 USB WLAN Adapter")},
- {PRISM_USB_DEVICE(0x2821, 0x3300, "Hawking HighDB USB Adapter")},
- {PRISM_USB_DEVICE
- (0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter")},
- {PRISM_USB_DEVICE(0x1668, 0x6106, "ROPEX FreeLan 802.11b USB Adapter")},
- {PRISM_USB_DEVICE
- (0x124a, 0x4017, "Pheenet WL-503IA 802.11b USB Adapter")},
- {PRISM_USB_DEVICE(0x0bb2, 0x0302, "Ambit Microsystems Corp.")},
- {PRISM_USB_DEVICE
- (0x9016, 0x182d, "Sitecom WL-022 802.11b USB Adapter")},
- {PRISM_USB_DEVICE
- (0x0543, 0x0f01, "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)")},
- { /* terminator */ }
+ PRISM_DEV(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS"),
+ PRISM_DEV(0x07aa, 0x0012, "Corega Wireless LAN USB Stick-11"),
+ PRISM_DEV(0x09aa, 0x3642, "Prism2.x 11Mbps WLAN USB Adapter"),
+ PRISM_DEV(0x1668, 0x0408, "Actiontec Prism2.5 11Mbps WLAN USB Adapter"),
+ PRISM_DEV(0x1668, 0x0421, "Actiontec Prism2.5 11Mbps WLAN USB Adapter"),
+ PRISM_DEV(0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps WLAN USB Adapter"),
+ PRISM_DEV(0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps WLAN USB Adapter"),
+ PRISM_DEV(0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter"),
+ PRISM_DEV(0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter"),
+ PRISM_DEV(0x08de, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter"),
+ PRISM_DEV(0x8086, 0x1111, "Intel PRO/Wireless 2011B LAN USB Adapter"),
+ PRISM_DEV(0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter"),
+ PRISM_DEV(0x045e, 0x006e, "Microsoft MN510 Wireless USB Adapter"),
+ PRISM_DEV(0x0967, 0x0204, "Acer Warplink USB Adapter"),
+ PRISM_DEV(0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated"),
+ PRISM_DEV(0x0cde, 0x0005, "Z-Com Xl735 Wireless 802.11b USB Adapter"),
+ PRISM_DEV(0x413c, 0x8100, "Dell TrueMobile 1180 Wireless USB Adapter"),
+ PRISM_DEV(0x0b3b, 0x1601, "ALLNET 0193 11Mbps WLAN USB Adapter"),
+ PRISM_DEV(0x0b3b, 0x1602, "ZyXEL ZyAIR B200 Wireless USB Adapter"),
+ PRISM_DEV(0x0baf, 0x00eb, "USRobotics USR1120 Wireless USB Adapter"),
+ PRISM_DEV(0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter"),
+ PRISM_DEV(0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter"),
+ PRISM_DEV(0x0846, 0x4110, "NetGear MA111"),
+ PRISM_DEV(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter"),
+ PRISM_DEV(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter"),
+ PRISM_DEV(0x2001, 0x3700, "DWL-122 Wireless USB Adapter"),
+ PRISM_DEV(0x2001, 0x3702, "DWL-120 Rev F Wireless USB Adapter"),
+ PRISM_DEV(0x50c2, 0x4013, "Averatec USB WLAN Adapter"),
+ PRISM_DEV(0x2c02, 0x14ea, "Planex GW-US11H WLAN USB Adapter"),
+ PRISM_DEV(0x124a, 0x168b, "Airvast PRISM3 WLAN USB Adapter"),
+ PRISM_DEV(0x083a, 0x3503, "T-Sinus 111 USB WLAN Adapter"),
+ PRISM_DEV(0x2821, 0x3300, "Hawking HighDB USB Adapter"),
+ PRISM_DEV(0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter"),
+ PRISM_DEV(0x1668, 0x6106, "ROPEX FreeLan 802.11b USB Adapter"),
+ PRISM_DEV(0x124a, 0x4017, "Pheenet WL-503IA 802.11b USB Adapter"),
+ 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)"),
+ PRISM_DEV(0x067c, 0x1022,
+ "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter"),
+ PRISM_DEV(0x049f, 0x0033,
+ "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter"),
+ { } /* terminator */
};
-
MODULE_DEVICE_TABLE(usb, usb_prism_tbl);
-/*----------------------------------------------------------------
-* prism2sta_probe_usb
-*
-* Probe routine called by the USB subsystem.
-*
-* Arguments:
-* dev ptr to the usb_device struct
-* ifnum interface number being offered
-*
-* Returns:
-* NULL - we're not claiming the device+interface
-* non-NULL - we are claiming the device+interface and
-* this is a ptr to the data we want back
-* when disconnect is called.
-*
-* Side effects:
-*
-* Call context:
-* I'm not sure, assume it's interrupt.
-*
-----------------------------------------------------------------*/
static int prism2sta_probe_usb(struct usb_interface *interface,
const struct usb_device_id *id)
{
prism2_reset_settletime, 0);
if (result != 0) {
result = -EIO;
- dev_err(&interface->dev, "hfa384x_corereset() failed.\n");
+ dev_err(&interface->dev,
+ "hfa384x_corereset() failed.\n");
goto failed_reset;
}
}
return result;
}
-/*----------------------------------------------------------------
-* prism2sta_disconnect_usb
-*
-* Called when a device previously claimed by probe is removed
-* from the USB.
-*
-* Arguments:
-* dev ptr to the usb_device struct
-* ptr ptr returned by probe() when the device
-* was claimed.
-*
-* Returns:
-* Nothing
-*
-* Side effects:
-*
-* Call context:
-* process
-----------------------------------------------------------------*/
static void prism2sta_disconnect_usb(struct usb_interface *interface)
{
wlandevice_t *wlandev;
wlandev = (wlandevice_t *) usb_get_intfdata(interface);
-
if (wlandev != NULL) {
LIST_HEAD(cleanlist);
struct list_head *entry;
{
hfa384x_t *hw = NULL;
wlandevice_t *wlandev;
+
wlandev = (wlandevice_t *) usb_get_intfdata(interface);
if (!wlandev)
return -ENODEV;
int result = 0;
hfa384x_t *hw = NULL;
wlandevice_t *wlandev;
+
wlandev = (wlandevice_t *) usb_get_intfdata(interface);
if (!wlandev)
return -ENODEV;
unsigned short ModeIdIndex = 0, ClockIndex = 0;
unsigned short RefreshRateTableIndex = 0;
int Clock;
+
InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
XGI_SearchModeID(ModeNo, &ModeIdIndex);
unsigned short HRE, HBE, HRS, HDE;
unsigned char sr_data, cr_data, cr_data2;
int B, C, D, F, temp, j;
+
InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
if (!XGI_SearchModeID(ModeNo, &ModeIdIndex))
return 0;
#ifndef _VB_DEF_
#define _VB_DEF_
-#include "../../video/sis/initdef.h"
+#include "../../video/fbdev/sis/initdef.h"
#define VB_XGI301C 0x0020 /* for 301C */
unsigned long P3c4, struct vb_device_info *pVBInfo)
{
unsigned long P3d4 = P3c4 + 0x10;
+
pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
XGINew_SetMemoryClock(pVBInfo);
u8 shift_factor, u8 mask1, u8 mask2)
{
u8 j;
+
for (j = 0; j < 4; j++) {
temp2 |= (((seed >> (2 * j)) & 0x03) << shift_factor);
xgifb_reg_set(P3d4, reg, temp2);
if (ChipType == XG27) {
unsigned char temp;
+
pVBInfo->MCLKData = XGI27New_MCLKData;
pVBInfo->CR40 = XGI27_cr41;
pVBInfo->XGINew_CR97 = 0xc1;
unsigned short temp;
int i;
+
xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
/* to fix XG42 single LCD sense to CRT+LCD */
#ifndef _VB_STRUCT_
#define _VB_STRUCT_
-#include "../../video/sis/vstruct.h"
+#include "../../video/fbdev/sis/vstruct.h"
struct XGI_LVDSCRT1HDataStruct {
unsigned char Reg[8];
#define _VGATYPES_
#include <linux/fb.h> /* for struct fb_var_screeninfo for sis.h */
-#include "../../video/sis/vgatypes.h"
-#include "../../video/sis/sis.h" /* for LCD_TYPE */
+#include "../../video/fbdev/sis/vgatypes.h"
+#include "../../video/fbdev/sis/sis.h" /* for LCD_TYPE */
#ifndef XGI_VB_CHIP_TYPE
enum XGI_VB_CHIP_TYPE {
status = serial8250_rx_chars(up, status);
}
serial8250_modem_status(up);
- if (status & UART_LSR_THRE)
+ if (!up->dma && (status & UART_LSR_THRE))
serial8250_tx_chars(up);
spin_unlock_irqrestore(&port->lock, flags);
struct uart_8250_port *p = param;
struct uart_8250_dma *dma = p->dma;
struct circ_buf *xmit = &p->port.state->xmit;
-
- dma->tx_running = 0;
+ unsigned long flags;
dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr,
UART_XMIT_SIZE, DMA_TO_DEVICE);
+ spin_lock_irqsave(&p->port.lock, flags);
+
+ dma->tx_running = 0;
+
xmit->tail += dma->tx_size;
xmit->tail &= UART_XMIT_SIZE - 1;
p->port.icount.tx += dma->tx_size;
if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port))
serial8250_tx_dma(p);
+
+ spin_unlock_irqrestore(&p->port.lock, flags);
}
static void __dma_rx_complete(void *param)
config SERIAL_TIMBERDALE
tristate "Support for timberdale UART"
select SERIAL_CORE
+ depends on X86_32 || COMPILE_TEST
---help---
Add support for UART controller on timberdale.
.src_addr = uap->port.mapbase + UART01x_DR,
.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
.direction = DMA_DEV_TO_MEM,
- .src_maxburst = uap->fifosize >> 1,
+ .src_maxburst = uap->fifosize >> 2,
.device_fc = false,
};
static int pl011_remove(struct amba_device *dev)
{
struct uart_amba_port *uap = amba_get_drvdata(dev);
+ bool busy = false;
int i;
uart_remove_one_port(&amba_reg, &uap->port);
for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
if (amba_ports[i] == uap)
amba_ports[i] = NULL;
+ else if (amba_ports[i])
+ busy = true;
pl011_dma_remove(uap);
- uart_unregister_driver(&amba_reg);
+ if (!busy)
+ uart_unregister_driver(&amba_reg);
return 0;
}
static void uart_clps711x_console_putchar(struct uart_port *port, int ch)
{
struct clps711x_port *s = dev_get_drvdata(port->dev);
+ u32 sysflg = 0;
/* Wait for FIFO is not full */
- while (1) {
- u32 sysflg = 0;
-
+ do {
regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg);
- if (!(sysflg & SYSFLG_UTXFF))
- break;
- cond_resched();
- }
+ } while (sysflg & SYSFLG_UTXFF);
writew(ch, port->membase + UARTDR_OFFSET);
}
{
struct uart_port *port = clps711x_uart.state[co->index].uart_port;
struct clps711x_port *s = dev_get_drvdata(port->dev);
+ u32 sysflg = 0;
uart_console_write(port, c, n, uart_clps711x_console_putchar);
/* Wait for transmitter to become empty */
- while (1) {
- u32 sysflg = 0;
-
+ do {
regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg);
- if (!(sysflg & SYSFLG_UBUSY))
- break;
- cond_resched();
- }
+ } while (sysflg & SYSFLG_UBUSY);
}
static int uart_clps711x_console_setup(struct console *co, char *options)
static const struct of_device_id efm32_uart_dt_ids[] = {
{
+ .compatible = "energymicro,efm32-uart",
+ }, {
+ /* doesn't follow the "vendor,device" scheme, don't use */
.compatible = "efm32,uart",
}, {
/* sentinel */
if (enable)
enable_irq(up->wakeirq);
else
- disable_irq(up->wakeirq);
+ disable_irq_nosync(up->wakeirq);
}
static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
{
struct omap_uart_port_info *pdata = dev_get_platdata(up->dev);
+ if (enable == up->wakeups_enabled)
+ return;
+
serial_omap_enable_wakeirq(up, enable);
+ up->wakeups_enabled = enable;
+
if (!pdata || !pdata->enable_wakeup)
return;
uart_suspend_port(&serial_omap_reg, &up->port);
flush_work(&up->qos_work);
+ if (device_may_wakeup(dev))
+ serial_omap_enable_wakeup(up, true);
+ else
+ serial_omap_enable_wakeup(up, false);
+
return 0;
}
{
struct uart_omap_port *up = dev_get_drvdata(dev);
+ if (device_may_wakeup(dev))
+ serial_omap_enable_wakeup(up, false);
+
uart_resume_port(&serial_omap_reg, &up->port);
return 0;
pm_runtime_disable(up->dev);
uart_remove_one_port(&serial_omap_reg, &up->port);
pm_qos_remove_request(&up->pm_qos_request);
+ device_init_wakeup(&dev->dev, false);
return 0;
}
up->context_loss_cnt = serial_omap_get_context_loss_count(up);
- if (device_may_wakeup(dev)) {
- if (!up->wakeups_enabled) {
- serial_omap_enable_wakeup(up, true);
- up->wakeups_enabled = true;
- }
- } else {
- if (up->wakeups_enabled) {
- serial_omap_enable_wakeup(up, false);
- up->wakeups_enabled = false;
- }
- }
+ serial_omap_enable_wakeup(up, true);
up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
schedule_work(&up->qos_work);
int loss_cnt = serial_omap_get_context_loss_count(up);
+ serial_omap_enable_wakeup(up, false);
+
if (loss_cnt < 0) {
dev_dbg(dev, "serial_omap_get_context_loss_count failed : %d\n",
loss_cnt);
static void s3c24xx_serial_put_poll_char(struct uart_port *port,
unsigned char c)
{
- unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON);
- unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON);
+ unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
+ unsigned int ucon = rd_regl(port, S3C2410_UCON);
/* not possible to xmit on unconfigured port */
if (!s3c24xx_port_configured(ucon))
while (!s3c24xx_serial_console_txrdy(port, ufcon))
cpu_relax();
- wr_regb(cons_uart, S3C2410_UTXH, c);
+ wr_regb(port, S3C2410_UTXH, c);
}
#endif /* CONFIG_CONSOLE_POLL */
static void
s3c24xx_serial_console_putchar(struct uart_port *port, int ch)
{
- unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON);
- unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON);
-
- /* not possible to xmit on unconfigured port */
- if (!s3c24xx_port_configured(ucon))
- return;
+ unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
while (!s3c24xx_serial_console_txrdy(port, ufcon))
- barrier();
- wr_regb(cons_uart, S3C2410_UTXH, ch);
+ cpu_relax();
+ wr_regb(port, S3C2410_UTXH, ch);
}
static void
s3c24xx_serial_console_write(struct console *co, const char *s,
unsigned int count)
{
+ unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON);
+
+ /* not possible to xmit on unconfigured port */
+ if (!s3c24xx_port_configured(ucon))
+ return;
+
uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar);
}
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->uart_port;
- if (!uart_circ_empty(&state->xmit) && state->xmit.buf &&
- !tty->stopped && !tty->hw_stopped)
+ if (!tty->stopped && !tty->hw_stopped)
port->ops->start_tx(port);
}
if (uport->type == PORT_UNKNOWN)
return 1;
+ /*
+ * Make sure the device is in D0 state.
+ */
+ uart_change_pm(state, UART_PM_STATE_ON);
+
/*
* Initialise and allocate the transmit and temporary
* buffer.
* If we fail to request resources for the
* new port, try to restore the old settings.
*/
- if (retval && old_type != PORT_UNKNOWN) {
+ if (retval) {
uport->iobase = old_iobase;
uport->type = old_type;
uport->hub6 = old_hub6;
uport->iotype = old_iotype;
uport->regshift = old_shift;
uport->mapbase = old_mapbase;
- retval = uport->ops->request_port(uport);
- /*
- * If we failed to restore the old settings,
- * we fail like this.
- */
- if (retval)
- uport->type = PORT_UNKNOWN;
- /*
- * We failed anyway.
- */
- retval = -EBUSY;
+ if (old_type != PORT_UNKNOWN) {
+ retval = uport->ops->request_port(uport);
+ /*
+ * If we failed to restore the old settings,
+ * we fail like this.
+ */
+ if (retval)
+ uport->type = PORT_UNKNOWN;
+
+ /*
+ * We failed anyway.
+ */
+ retval = -EBUSY;
+ }
+
/* Added to return the correct error -Ram Gupta */
goto exit;
}
clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
spin_unlock_irqrestore(&port->lock, flags);
tty_port_tty_set(port, NULL);
+ if (!uart_console(state->uart_port))
+ uart_change_pm(state, UART_PM_STATE_OFF);
wake_up_interruptible(&port->open_wait);
wake_up_interruptible(&port->delta_msr_wait);
}
goto err_dec_count;
}
- /*
- * Make sure the device is in D0 state.
- */
- if (port->count == 1)
- uart_change_pm(state, UART_PM_STATE_ON);
-
/*
* Start up the serial port.
*/
status & ASC_STA_OE) {
if (c & ASC_RXBUF_FE) {
- if (c == ASC_RXBUF_FE) {
+ if (c == (ASC_RXBUF_FE | ASC_RXBUF_DUMMY_RX)) {
port->icount.brk++;
if (uart_handle_break(port))
continue;
flag = TTY_FRAME;
}
- if (uart_handle_sysrq_char(port, c))
+ if (uart_handle_sysrq_char(port, c & 0xff))
continue;
uart_insert_char(port, c, ASC_RXBUF_DUMMY_OE, c & 0xff, flag);
if (change || left < size) {
/* This is the slow path - looking for new buffers to use */
if ((n = tty_buffer_alloc(port, size)) != NULL) {
+ unsigned long iflags;
+
n->flags = flags;
buf->tail = n;
+
+ spin_lock_irqsave(&buf->flush_lock, iflags);
b->commit = b->used;
- smp_mb();
b->next = n;
+ spin_unlock_irqrestore(&buf->flush_lock, iflags);
+
} else if (change)
size = 0;
else
mutex_lock(&buf->lock);
while (1) {
+ unsigned long flags;
struct tty_buffer *head = buf->head;
int count;
if (atomic_read(&buf->priority))
break;
+ spin_lock_irqsave(&buf->flush_lock, flags);
count = head->commit - head->read;
if (!count) {
- if (head->next == NULL)
+ if (head->next == NULL) {
+ spin_unlock_irqrestore(&buf->flush_lock, flags);
break;
+ }
buf->head = head->next;
+ spin_unlock_irqrestore(&buf->flush_lock, flags);
tty_buffer_free(port, head);
continue;
}
+ spin_unlock_irqrestore(&buf->flush_lock, flags);
count = receive_buf(tty, head, count);
if (!count)
struct tty_bufhead *buf = &port->buf;
mutex_init(&buf->lock);
+ spin_lock_init(&buf->flush_lock);
tty_buffer_reset(&buf->sentinel, 0);
buf->head = &buf->sentinel;
buf->tail = &buf->sentinel;
spin_lock_irq(¤t->sighand->siglock);
put_pid(current->signal->tty_old_pgrp);
current->signal->tty_old_pgrp = NULL;
- spin_unlock_irq(¤t->sighand->siglock);
- tty = get_current_tty();
+ tty = tty_kref_get(current->signal->tty);
if (tty) {
unsigned long flags;
spin_lock_irqsave(&tty->ctrl_lock, flags);
#endif
}
+ spin_unlock_irq(¤t->sighand->siglock);
/* Now clear signal->tty under the lock */
read_lock(&tasklist_lock);
session_clear_tty(task_session(current));
}
}
+/**
+ * ci_usb_phy_init: initialize phy according to different phy type
+ * @ci: the controller
+ *
+ * This function returns an error code if usb_phy_init has failed
+ */
+static int ci_usb_phy_init(struct ci_hdrc *ci)
+{
+ int ret;
+
+ switch (ci->platdata->phy_mode) {
+ case USBPHY_INTERFACE_MODE_UTMI:
+ case USBPHY_INTERFACE_MODE_UTMIW:
+ case USBPHY_INTERFACE_MODE_HSIC:
+ ret = usb_phy_init(ci->transceiver);
+ if (ret)
+ return ret;
+ hw_phymode_configure(ci);
+ break;
+ case USBPHY_INTERFACE_MODE_ULPI:
+ case USBPHY_INTERFACE_MODE_SERIAL:
+ hw_phymode_configure(ci);
+ ret = usb_phy_init(ci->transceiver);
+ if (ret)
+ return ret;
+ break;
+ default:
+ ret = usb_phy_init(ci->transceiver);
+ }
+
+ return ret;
+}
+
/**
* hw_device_reset: resets chip (execute without interruption)
* @ci: the controller
return -ENODEV;
}
- hw_phymode_configure(ci);
-
if (ci->platdata->phy)
ci->transceiver = ci->platdata->phy;
else
return -EPROBE_DEFER;
}
- ret = usb_phy_init(ci->transceiver);
+ ret = ci_usb_phy_init(ci);
if (ret) {
dev_err(dev, "unable to init phy: %d\n", ret);
return ret;
if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) {
dev_err(&acm->control->dev,
"%s - usb_submit_urb(ctrl irq) failed\n", __func__);
+ usb_autopm_put_interface(acm->control);
goto error_submit_urb;
}
acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS;
if (acm_set_control(acm, acm->ctrlout) < 0 &&
- (acm->ctrl_caps & USB_CDC_CAP_LINE))
+ (acm->ctrl_caps & USB_CDC_CAP_LINE)) {
+ usb_autopm_put_interface(acm->control);
goto error_set_control;
+ }
usb_autopm_put_interface(acm->control);
error_set_control:
usb_kill_urb(acm->ctrlurb);
error_submit_urb:
- usb_autopm_put_interface(acm->control);
error_get_interface:
disconnected:
mutex_unlock(&acm->mutex);
},
/* Motorola H24 HSPA module: */
{ USB_DEVICE(0x22b8, 0x2d91) }, /* modem */
- { USB_DEVICE(0x22b8, 0x2d92) }, /* modem + diagnostics */
- { USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port */
- { USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics */
- { USB_DEVICE(0x22b8, 0x2d96) }, /* modem + NMEA */
- { USB_DEVICE(0x22b8, 0x2d97) }, /* modem + diagnostics + NMEA */
- { USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port + NMEA */
- { USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */
+ { USB_DEVICE(0x22b8, 0x2d92), /* modem + diagnostics */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
+ { USB_DEVICE(0x22b8, 0x2d93), /* modem + AT port */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
+ { USB_DEVICE(0x22b8, 0x2d95), /* modem + AT port + diagnostics */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
+ { USB_DEVICE(0x22b8, 0x2d96), /* modem + NMEA */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
+ { USB_DEVICE(0x22b8, 0x2d97), /* modem + diagnostics + NMEA */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
+ { USB_DEVICE(0x22b8, 0x2d99), /* modem + AT port + NMEA */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
+ { USB_DEVICE(0x22b8, 0x2d9a), /* modem + AT port + diagnostics + NMEA */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
{ USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */
.driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on
PCI_SLOT(companion->devfn) != slot)
continue;
companion_hcd = pci_get_drvdata(companion);
- if (!companion_hcd)
+ if (!companion_hcd || !companion_hcd->self.root_hub)
continue;
fn(pdev, hcd, companion, companion_hcd);
}
spin_lock_irqsave(&dwc->lock, flags);
+ dwc3_event_buffers_setup(dwc);
switch (dwc->dr_mode) {
case USB_DR_MODE_PERIPHERAL:
case USB_DR_MODE_OTG:
/* FALLTHROUGH */
case USB_DR_MODE_HOST:
default:
- dwc3_event_buffers_setup(dwc);
break;
}
* improve this algorithm so that we better use the internal
* FIFO space
*/
- for (num = 0; num < DWC3_ENDPOINTS_NUM; num++) {
- struct dwc3_ep *dep = dwc->eps[num];
- int fifo_number = dep->number >> 1;
+ for (num = 0; num < dwc->num_in_eps; num++) {
+ /* bit0 indicates direction; 1 means IN ep */
+ struct dwc3_ep *dep = dwc->eps[(num << 1) | 1];
int mult = 1;
int tmp;
- if (!(dep->number & 1))
- continue;
-
if (!(dep->flags & DWC3_EP_ENABLED))
continue;
dev_vdbg(dwc->dev, "%s: Fifo Addr %04x Size %d\n",
dep->name, last_fifo_depth, fifo_size & 0xffff);
- dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(fifo_number),
- fifo_size);
+ dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num), fifo_size);
last_fifo_depth += (fifo_size & 0xffff);
}
*/
struct usb_gadget *gadget = epfile->ffs->gadget;
+ spin_lock_irq(&epfile->ffs->eps_lock);
+ /* In the meantime, endpoint got disabled or changed. */
+ if (epfile->ep != ep) {
+ spin_unlock_irq(&epfile->ffs->eps_lock);
+ return -ESHUTDOWN;
+ }
/*
* Controller may require buffer size to be aligned to
* maxpacketsize of an out endpoint.
data_len = io_data->read ?
usb_ep_align_maybe(gadget, ep->ep, io_data->len) :
io_data->len;
+ spin_unlock_irq(&epfile->ffs->eps_lock);
data = kmalloc(data_len, GFP_KERNEL);
if (unlikely(!data))
if (skb2)
rndis_add_hdr(skb2);
- dev_kfree_skb_any(skb);
+ dev_kfree_skb(skb);
return skb2;
}
struct fsl_udc *udc;
udc = container_of(gadget, struct fsl_udc, gadget);
+
+ if (!udc->vbus_active)
+ return -EOPNOTSUPP;
+
udc->softconnect = (is_on != 0);
if (can_pullup(udc))
fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP),
if (!udc_controller)
return -ENODEV;
- usb_del_gadget_udc(&udc_controller->gadget);
udc_controller->done = &done;
+ usb_del_gadget_udc(&udc_controller->gadget);
fsl_udc_clk_release();
return -ESRCH;
/* fake probe to determine $CHIP */
+ CHIP = NULL;
usb_gadget_probe_driver(&probe_driver);
if (!CHIP)
return -ENODEV;
#include <asm/byteorder.h>
#include <asm/unaligned.h>
+#include "u_rndis.h"
#undef VERBOSE_DEBUG
#define UETH__VERSION "29-May-2008"
-#define GETHER_NAPI_WEIGHT 32
-
struct eth_dev {
/* lock is held while accessing port_usb
*/
struct sk_buff_head *list);
struct work_struct work;
- struct napi_struct rx_napi;
unsigned long todo;
#define WORK_RX_MEMORY 0
DBG(dev, "rx submit --> %d\n", retval);
if (skb)
dev_kfree_skb_any(skb);
+ spin_lock_irqsave(&dev->req_lock, flags);
+ list_add(&req->list, &dev->rx_reqs);
+ spin_unlock_irqrestore(&dev->req_lock, flags);
}
return retval;
}
static void rx_complete(struct usb_ep *ep, struct usb_request *req)
{
- struct sk_buff *skb = req->context;
+ struct sk_buff *skb = req->context, *skb2;
struct eth_dev *dev = ep->driver_data;
int status = req->status;
- bool rx_queue = 0;
switch (status) {
} else {
skb_queue_tail(&dev->rx_frames, skb);
}
- if (!status)
- rx_queue = 1;
+ skb = NULL;
+
+ skb2 = skb_dequeue(&dev->rx_frames);
+ while (skb2) {
+ if (status < 0
+ || ETH_HLEN > skb2->len
+ || skb2->len > VLAN_ETH_FRAME_LEN) {
+ dev->net->stats.rx_errors++;
+ dev->net->stats.rx_length_errors++;
+ DBG(dev, "rx length %d\n", skb2->len);
+ dev_kfree_skb_any(skb2);
+ goto next_frame;
+ }
+ skb2->protocol = eth_type_trans(skb2, dev->net);
+ dev->net->stats.rx_packets++;
+ dev->net->stats.rx_bytes += skb2->len;
+
+ /* no buffer copies needed, unless hardware can't
+ * use skb buffers.
+ */
+ status = netif_rx(skb2);
+next_frame:
+ skb2 = skb_dequeue(&dev->rx_frames);
+ }
break;
/* software-driven interface shutdown */
/* FALLTHROUGH */
default:
- rx_queue = 1;
- dev_kfree_skb_any(skb);
dev->net->stats.rx_errors++;
DBG(dev, "rx status %d\n", status);
break;
}
+ if (skb)
+ dev_kfree_skb_any(skb);
+ if (!netif_running(dev->net)) {
clean:
spin_lock(&dev->req_lock);
list_add(&req->list, &dev->rx_reqs);
spin_unlock(&dev->req_lock);
-
- if (rx_queue && likely(napi_schedule_prep(&dev->rx_napi)))
- __napi_schedule(&dev->rx_napi);
+ req = NULL;
+ }
+ if (req)
+ rx_submit(dev, req, GFP_ATOMIC);
}
static int prealloc(struct list_head *list, struct usb_ep *ep, unsigned n)
{
struct usb_request *req;
unsigned long flags;
- int rx_counts = 0;
/* fill unused rxq slots with some skb */
spin_lock_irqsave(&dev->req_lock, flags);
while (!list_empty(&dev->rx_reqs)) {
-
- if (++rx_counts > qlen(dev->gadget, dev->qmult))
- break;
-
req = container_of(dev->rx_reqs.next,
struct usb_request, list);
list_del_init(&req->list);
spin_unlock_irqrestore(&dev->req_lock, flags);
if (rx_submit(dev, req, gfp_flags) < 0) {
- spin_lock_irqsave(&dev->req_lock, flags);
- list_add(&req->list, &dev->rx_reqs);
- spin_unlock_irqrestore(&dev->req_lock, flags);
defer_kevent(dev, WORK_RX_MEMORY);
return;
}
spin_unlock_irqrestore(&dev->req_lock, flags);
}
-static int gether_poll(struct napi_struct *napi, int budget)
-{
- struct eth_dev *dev = container_of(napi, struct eth_dev, rx_napi);
- struct sk_buff *skb;
- unsigned int work_done = 0;
- int status = 0;
-
- while ((skb = skb_dequeue(&dev->rx_frames))) {
- if (status < 0
- || ETH_HLEN > skb->len
- || skb->len > VLAN_ETH_FRAME_LEN) {
- dev->net->stats.rx_errors++;
- dev->net->stats.rx_length_errors++;
- DBG(dev, "rx length %d\n", skb->len);
- dev_kfree_skb_any(skb);
- continue;
- }
- skb->protocol = eth_type_trans(skb, dev->net);
- dev->net->stats.rx_packets++;
- dev->net->stats.rx_bytes += skb->len;
-
- status = netif_rx_ni(skb);
- }
-
- if (netif_running(dev->net)) {
- rx_fill(dev, GFP_KERNEL);
- work_done++;
- }
-
- if (work_done < budget)
- napi_complete(&dev->rx_napi);
-
- return work_done;
-}
-
static void eth_work(struct work_struct *work)
{
struct eth_dev *dev = container_of(work, struct eth_dev, work);
/* and open the tx floodgates */
atomic_set(&dev->tx_qlen, 0);
netif_wake_queue(dev->net);
- napi_enable(&dev->rx_napi);
}
static int eth_open(struct net_device *net)
unsigned long flags;
VDBG(dev, "%s\n", __func__);
- napi_disable(&dev->rx_napi);
netif_stop_queue(net);
DBG(dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n",
return ERR_PTR(-ENOMEM);
dev = netdev_priv(net);
- netif_napi_add(net, &dev->rx_napi, gether_poll, GETHER_NAPI_WEIGHT);
spin_lock_init(&dev->lock);
spin_lock_init(&dev->req_lock);
INIT_WORK(&dev->work, eth_work);
return ERR_PTR(-ENOMEM);
dev = netdev_priv(net);
- netif_napi_add(net, &dev->rx_napi, gether_poll, GETHER_NAPI_WEIGHT);
spin_lock_init(&dev->lock);
spin_lock_init(&dev->req_lock);
INIT_WORK(&dev->work, eth_work);
{
struct eth_dev *dev = link->ioport;
struct usb_request *req;
- struct sk_buff *skb;
WARN_ON(!dev);
if (!dev)
spin_lock(&dev->req_lock);
}
spin_unlock(&dev->req_lock);
-
- spin_lock(&dev->rx_frames.lock);
- while ((skb = __skb_dequeue(&dev->rx_frames)))
- dev_kfree_skb_any(skb);
- spin_unlock(&dev->rx_frames.lock);
-
link->in_ep->driver_data = NULL;
link->in_ep->desc = NULL;
ss_opts->isoc_interval = gzero_options.isoc_interval;
ss_opts->isoc_maxpacket = gzero_options.isoc_maxpacket;
ss_opts->isoc_mult = gzero_options.isoc_mult;
- ss_opts->isoc_maxburst = gzero_options.isoc_maxpacket;
+ ss_opts->isoc_maxburst = gzero_options.isoc_maxburst;
ss_opts->bulk_buflen = gzero_options.bulk_buflen;
func_ss = usb_get_function(func_inst_ss);
int rc;
rc = ehci_suspend(hcd, do_wakeup);
+ if (rc)
+ return rc;
if (exynos_ehci->otg)
exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
int ret;
ret = ehci_suspend(hcd, do_wakeup);
+ if (ret)
+ return ret;
if (pdata->power_suspend)
pdata->power_suspend(pdev);
}
};
+static int tegra_ehci_reset(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ int retval;
+ int txfifothresh;
+
+ retval = ehci_setup(hcd);
+ if (retval)
+ return retval;
+
+ /*
+ * We should really pull this value out of tegra_ehci_soc_config, but
+ * to avoid needing access to it, make use of the fact that Tegra20 is
+ * the only one so far that needs a value of 10, and Tegra20 is the
+ * only one which doesn't set has_hostpc.
+ */
+ txfifothresh = ehci->has_hostpc ? 0x10 : 10;
+ ehci_writel(ehci, txfifothresh << 16, &ehci->regs->txfill_tuning);
+
+ return 0;
+}
+
static const struct ehci_driver_overrides tegra_overrides __initconst = {
.extra_priv_size = sizeof(struct tegra_ehci_hcd),
+ .reset = tegra_ehci_reset,
};
static int __init ehci_tegra_init(void)
u16 wIndex, char *buf, u16 wLength)
{
struct jz4740_ohci_hcd *jz4740_ohci = hcd_to_jz4740_hcd(hcd);
- int ret;
+ int ret = 0;
switch (typeReq) {
- case SetHubFeature:
+ case SetPortFeature:
if (wValue == USB_PORT_FEAT_POWER)
ret = ohci_jz4740_set_vbus_power(jz4740_ohci, true);
break;
- case ClearHubFeature:
+ case ClearPortFeature:
if (wValue == USB_PORT_FEAT_POWER)
ret = ohci_jz4740_set_vbus_power(jz4740_ohci, false);
break;
*/
if (pdev->subsystem_vendor == PCI_VENDOR_ID_HP)
xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
+
+ xhci->quirks |= XHCI_SPURIOUS_REBOOT;
}
if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
}
if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
- pdev->device == 0x0015 &&
- pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG &&
- pdev->subsystem_device == 0xc0cd)
+ pdev->device == 0x0015)
xhci->quirks |= XHCI_RESET_ON_RESUME;
if (pdev->vendor == PCI_VENDOR_ID_VIA)
xhci->quirks |= XHCI_RESET_ON_RESUME;
struct xhci_ring *ep_ring;
struct xhci_generic_trb *trb;
dma_addr_t addr;
+ u64 hw_dequeue;
ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id,
ep_index, stream_id);
stream_id);
return;
}
- state->new_cycle_state = 0;
- xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
- "Finding segment containing stopped TRB.");
- state->new_deq_seg = find_trb_seg(cur_td->start_seg,
- dev->eps[ep_index].stopped_trb,
- &state->new_cycle_state);
- if (!state->new_deq_seg) {
- WARN_ON(1);
- return;
- }
/* Dig out the cycle state saved by the xHC during the stop ep cmd */
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
if (ep->ep_state & EP_HAS_STREAMS) {
struct xhci_stream_ctx *ctx =
&ep->stream_info->stream_ctx_array[stream_id];
- state->new_cycle_state = 0x1 & le64_to_cpu(ctx->stream_ring);
+ hw_dequeue = le64_to_cpu(ctx->stream_ring);
} else {
struct xhci_ep_ctx *ep_ctx
= xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
- state->new_cycle_state = 0x1 & le64_to_cpu(ep_ctx->deq);
+ hw_dequeue = le64_to_cpu(ep_ctx->deq);
}
+ /* Find virtual address and segment of hardware dequeue pointer */
+ state->new_deq_seg = ep_ring->deq_seg;
+ state->new_deq_ptr = ep_ring->dequeue;
+ while (xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr)
+ != (dma_addr_t)(hw_dequeue & ~0xf)) {
+ next_trb(xhci, ep_ring, &state->new_deq_seg,
+ &state->new_deq_ptr);
+ if (state->new_deq_ptr == ep_ring->dequeue) {
+ WARN_ON(1);
+ return;
+ }
+ }
+ /*
+ * Find cycle state for last_trb, starting at old cycle state of
+ * hw_dequeue. If there is only one segment ring, find_trb_seg() will
+ * return immediately and cannot toggle the cycle state if this search
+ * wraps around, so add one more toggle manually in that case.
+ */
+ state->new_cycle_state = hw_dequeue & 0x1;
+ if (ep_ring->first_seg == ep_ring->first_seg->next &&
+ cur_td->last_trb < state->new_deq_ptr)
+ state->new_cycle_state ^= 0x1;
+
state->new_deq_ptr = cur_td->last_trb;
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"Finding segment containing last TRB in TD.");
state->new_deq_seg = find_trb_seg(state->new_deq_seg,
- state->new_deq_ptr,
- &state->new_cycle_state);
+ state->new_deq_ptr, &state->new_cycle_state);
if (!state->new_deq_seg) {
WARN_ON(1);
return;
}
+ /* Increment to find next TRB after last_trb. Cycle if appropriate. */
trb = &state->new_deq_ptr->generic;
if (TRB_TYPE_LINK_LE32(trb->field[3]) &&
(trb->field[3] & cpu_to_le32(LINK_TOGGLE)))
state->new_cycle_state ^= 0x1;
next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr);
- /*
- * If there is only one segment in a ring, find_trb_seg()'s while loop
- * will not run, and it will return before it has a chance to see if it
- * needs to toggle the cycle bit. It can't tell if the stalled transfer
- * ended just before the link TRB on a one-segment ring, or if the TD
- * wrapped around the top of the ring, because it doesn't have the TD in
- * question. Look for the one-segment case where stalled TRB's address
- * is greater than the new dequeue pointer address.
- */
- if (ep_ring->first_seg == ep_ring->first_seg->next &&
- state->new_deq_ptr < dev->eps[ep_index].stopped_trb)
- state->new_cycle_state ^= 0x1;
+ /* Don't update the ring cycle state for the producer (us). */
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"Cycle state = 0x%x", state->new_cycle_state);
- /* Don't update the ring cycle state for the producer (us). */
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"New dequeue segment = %p (virtual)",
state->new_deq_seg);
if (list_empty(&ep->cancelled_td_list)) {
xhci_stop_watchdog_timer_in_irq(xhci, ep);
ep->stopped_td = NULL;
- ep->stopped_trb = NULL;
ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
return;
}
ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
}
- /* Clear stopped_td and stopped_trb if endpoint is not halted */
- if (!(ep->ep_state & EP_HALTED)) {
+ /* Clear stopped_td if endpoint is not halted */
+ if (!(ep->ep_state & EP_HALTED))
ep->stopped_td = NULL;
- ep->stopped_trb = NULL;
- }
/*
* Drop the lock and complete the URBs in the cancelled TD list.
struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];
ep->ep_state |= EP_HALTED;
ep->stopped_td = td;
- ep->stopped_trb = event_trb;
ep->stopped_stream = stream_id;
xhci_queue_reset_ep(xhci, slot_id, ep_index);
xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index);
ep->stopped_td = NULL;
- ep->stopped_trb = NULL;
ep->stopped_stream = 0;
xhci_ring_cmd_db(xhci);
* the ring dequeue pointer or take this TD off any lists yet.
*/
ep->stopped_td = td;
- ep->stopped_trb = event_trb;
return 0;
} else {
if (trb_comp_code == COMP_STALL) {
* USB class driver clear the stall later.
*/
ep->stopped_td = td;
- ep->stopped_trb = event_trb;
ep->stopped_stream = ep_ring->stream_id;
} else if (xhci_requires_manual_halt_cleanup(xhci,
ep_ctx, trb_comp_code)) {
#else
-static int xhci_try_enable_msi(struct usb_hcd *hcd)
+static inline int xhci_try_enable_msi(struct usb_hcd *hcd)
{
return 0;
}
-static void xhci_cleanup_msix(struct xhci_hcd *xhci)
+static inline void xhci_cleanup_msix(struct xhci_hcd *xhci)
{
}
-static void xhci_msix_sync_irqs(struct xhci_hcd *xhci)
+static inline void xhci_msix_sync_irqs(struct xhci_hcd *xhci)
{
}
xhci_ring_cmd_db(xhci);
}
virt_ep->stopped_td = NULL;
- virt_ep->stopped_trb = NULL;
virt_ep->stopped_stream = 0;
spin_unlock_irqrestore(&xhci->lock, flags);
#define EP_GETTING_NO_STREAMS (1 << 5)
/* ---- Related to URB cancellation ---- */
struct list_head cancelled_td_list;
- /* The TRB that was last reported in a stopped endpoint ring */
- union xhci_trb *stopped_trb;
struct xhci_td *stopped_td;
unsigned int stopped_stream;
/* Watchdog timer for stop endpoint command to cancel URBs */
struct dsps_glue *glue = dev_get_drvdata(dev->parent);
del_timer_sync(&glue->timer);
-
usb_phy_shutdown(musb->xceiv);
+ debugfs_remove_recursive(glue->dbgfs_root);
+
return 0;
}
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- debugfs_remove_recursive(glue->dbgfs_root);
-
return 0;
}
{
struct omap2430_glue *glue = container_of(mailbox_work,
struct omap2430_glue, omap_musb_mailbox_work);
+ struct musb *musb = glue_to_musb(glue);
+ struct device *dev = musb->controller;
+
+ pm_runtime_get_sync(dev);
omap_musb_set_mailbox(glue);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
}
static irqreturn_t omap2430_musb_interrupt(int irq, void *__hci)
omap_musb_set_mailbox(glue);
phy_init(musb->phy);
+ phy_power_on(musb->phy);
pm_runtime_put_noidle(musb->controller);
return 0;
del_timer_sync(&musb_idle_timer);
omap2430_low_level_exit(musb);
+ phy_power_off(musb->phy);
phy_exit(musb->phy);
return 0;
#include <linux/err.h>
#include <linux/of.h>
#include <linux/io.h>
+#include <linux/delay.h>
#include "am35x-phy-control.h"
struct am335x_control_usb {
}
writel(val, usb_ctrl->phy_reg + reg);
+
+ /*
+ * Give the PHY ~1ms to complete the power up operation.
+ * Tests have shown unstable behaviour if other USB PHY related
+ * registers are written too shortly after such a transition.
+ */
+ if (on)
+ mdelay(1);
}
static const struct phy_control ctrl_am335x = {
if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) {
pr_debug("PHY: unable to find transceiver of type %s\n",
usb_phy_type_string(type));
+ if (!IS_ERR(phy))
+ phy = ERR_PTR(-ENODEV);
+
goto err0;
}
{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
{ USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */
{ USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */
+ { USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */
{ USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */
{ USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
{ USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) },
/* Cressi Devices */
{ USB_DEVICE(FTDI_VID, FTDI_CRESSI_PID) },
+ /* Brainboxes Devices */
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_001_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_012_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_023_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_034_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_101_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_1_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_2_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_3_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_4_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_5_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_6_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_7_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_8_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_257_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_1_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_2_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_3_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_4_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_313_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_324_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_1_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_2_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_357_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_1_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_2_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_3_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_1_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_2_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_1_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) },
{ } /* Terminating entry */
};
* Manufacturer: Cressi
*/
#define FTDI_CRESSI_PID 0x87d0
+
+/*
+ * Brainboxes devices
+ */
+#define BRAINBOXES_VID 0x05d1
+#define BRAINBOXES_VX_001_PID 0x1001 /* VX-001 ExpressCard 1 Port RS232 */
+#define BRAINBOXES_VX_012_PID 0x1002 /* VX-012 ExpressCard 2 Port RS232 */
+#define BRAINBOXES_VX_023_PID 0x1003 /* VX-023 ExpressCard 1 Port RS422/485 */
+#define BRAINBOXES_VX_034_PID 0x1004 /* VX-034 ExpressCard 2 Port RS422/485 */
+#define BRAINBOXES_US_101_PID 0x1011 /* US-101 1xRS232 */
+#define BRAINBOXES_US_324_PID 0x1013 /* US-324 1xRS422/485 1Mbaud */
+#define BRAINBOXES_US_606_1_PID 0x2001 /* US-606 6 Port RS232 Serial Port 1 and 2 */
+#define BRAINBOXES_US_606_2_PID 0x2002 /* US-606 6 Port RS232 Serial Port 3 and 4 */
+#define BRAINBOXES_US_606_3_PID 0x2003 /* US-606 6 Port RS232 Serial Port 4 and 6 */
+#define BRAINBOXES_US_701_1_PID 0x2011 /* US-701 4xRS232 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_701_2_PID 0x2012 /* US-701 4xRS422 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_279_1_PID 0x2021 /* US-279 8xRS422 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_279_2_PID 0x2022 /* US-279 8xRS422 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_279_3_PID 0x2023 /* US-279 8xRS422 1Mbaud Port 5 and 6 */
+#define BRAINBOXES_US_279_4_PID 0x2024 /* US-279 8xRS422 1Mbaud Port 7 and 8 */
+#define BRAINBOXES_US_346_1_PID 0x3011 /* US-346 4xRS422/485 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_346_2_PID 0x3012 /* US-346 4xRS422/485 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_257_PID 0x5001 /* US-257 2xRS232 1Mbaud */
+#define BRAINBOXES_US_313_PID 0x6001 /* US-313 2xRS422/485 1Mbaud */
+#define BRAINBOXES_US_357_PID 0x7001 /* US_357 1xRS232/422/485 */
+#define BRAINBOXES_US_842_1_PID 0x8001 /* US-842 8xRS422/485 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_842_2_PID 0x8002 /* US-842 8xRS422/485 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_842_3_PID 0x8003 /* US-842 8xRS422/485 1Mbaud Port 5 and 6 */
+#define BRAINBOXES_US_842_4_PID 0x8004 /* US-842 8xRS422/485 1Mbaud Port 7 and 8 */
+#define BRAINBOXES_US_160_1_PID 0x9001 /* US-160 16xRS232 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_160_2_PID 0x9002 /* US-160 16xRS232 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_160_3_PID 0x9003 /* US-160 16xRS232 1Mbaud Port 5 and 6 */
+#define BRAINBOXES_US_160_4_PID 0x9004 /* US-160 16xRS232 1Mbaud Port 7 and 8 */
+#define BRAINBOXES_US_160_5_PID 0x9005 /* US-160 16xRS232 1Mbaud Port 9 and 10 */
+#define BRAINBOXES_US_160_6_PID 0x9006 /* US-160 16xRS232 1Mbaud Port 11 and 12 */
+#define BRAINBOXES_US_160_7_PID 0x9007 /* US-160 16xRS232 1Mbaud Port 13 and 14 */
+#define BRAINBOXES_US_160_8_PID 0x9008 /* US-160 16xRS232 1Mbaud Port 15 and 16 */
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/serial.h>
+#include <linux/swab.h>
#include <linux/kfifo.h>
#include <linux/ioctl.h>
#include <linux/firmware.h>
{
int status = 0;
__u8 read_length;
- __be16 be_start_address;
+ u16 be_start_address;
dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, length);
if (read_length > 1) {
dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, read_length);
}
- be_start_address = cpu_to_be16(start_address);
+ /*
+ * NOTE: Must use swab as wIndex is sent in little-endian
+ * byte order regardless of host byte order.
+ */
+ be_start_address = swab16((u16)start_address);
status = ti_vread_sync(dev, UMPC_MEMORY_READ,
(__u16)address_type,
- (__force __u16)be_start_address,
+ be_start_address,
buffer, read_length);
if (status) {
struct device *dev = &serial->serial->dev->dev;
int status = 0;
int write_length;
- __be16 be_start_address;
+ u16 be_start_address;
/* We can only send a maximum of 1 aligned byte page at a time */
__func__, start_address, write_length);
usb_serial_debug_data(dev, __func__, write_length, buffer);
- /* Write first page */
- be_start_address = cpu_to_be16(start_address);
+ /*
+ * Write first page.
+ *
+ * NOTE: Must use swab as wIndex is sent in little-endian byte order
+ * regardless of host byte order.
+ */
+ be_start_address = swab16((u16)start_address);
status = ti_vsend_sync(serial->serial->dev,
UMPC_MEMORY_WRITE, (__u16)address_type,
- (__force __u16)be_start_address,
+ be_start_address,
buffer, write_length);
if (status) {
dev_dbg(dev, "%s - ERROR %d\n", __func__, status);
__func__, start_address, write_length);
usb_serial_debug_data(dev, __func__, write_length, buffer);
- /* Write next page */
- be_start_address = cpu_to_be16(start_address);
+ /*
+ * Write next page.
+ *
+ * NOTE: Must use swab as wIndex is sent in little-endian byte
+ * order regardless of host byte order.
+ */
+ be_start_address = swab16((u16)start_address);
status = ti_vsend_sync(serial->serial->dev, UMPC_MEMORY_WRITE,
(__u16)address_type,
- (__force __u16)be_start_address,
+ be_start_address,
buffer, write_length);
if (status) {
dev_err(dev, "%s - ERROR %d\n", __func__, status);
if (rom_desc->Type == desc_type)
return start_address;
- start_address = start_address + sizeof(struct ti_i2c_desc)
- + rom_desc->Size;
+ start_address = start_address + sizeof(struct ti_i2c_desc) +
+ le16_to_cpu(rom_desc->Size);
} while ((start_address < TI_MAX_I2C_SIZE) && rom_desc->Type);
__u16 i;
__u8 cs = 0;
- for (i = 0; i < rom_desc->Size; i++)
+ for (i = 0; i < le16_to_cpu(rom_desc->Size); i++)
cs = (__u8)(cs + buffer[i]);
if (cs != rom_desc->CheckSum) {
break;
if ((start_address + sizeof(struct ti_i2c_desc) +
- rom_desc->Size) > TI_MAX_I2C_SIZE) {
+ le16_to_cpu(rom_desc->Size)) > TI_MAX_I2C_SIZE) {
status = -ENODEV;
dev_dbg(dev, "%s - structure too big, erroring out.\n", __func__);
break;
/* Read the descriptor data */
status = read_rom(serial, start_address +
sizeof(struct ti_i2c_desc),
- rom_desc->Size, buffer);
+ le16_to_cpu(rom_desc->Size),
+ buffer);
if (status)
break;
break;
}
start_address = start_address + sizeof(struct ti_i2c_desc) +
- rom_desc->Size;
+ le16_to_cpu(rom_desc->Size);
} while ((rom_desc->Type != I2C_DESC_TYPE_ION) &&
(start_address < TI_MAX_I2C_SIZE));
/* Read the descriptor data */
status = read_rom(serial, start_address+sizeof(struct ti_i2c_desc),
- rom_desc->Size, buffer);
+ le16_to_cpu(rom_desc->Size), buffer);
if (status)
goto exit;
#define QUALCOMM_VENDOR_ID 0x05C6
#define CMOTECH_VENDOR_ID 0x16d8
-#define CMOTECH_PRODUCT_6008 0x6008
-#define CMOTECH_PRODUCT_6280 0x6280
+#define CMOTECH_PRODUCT_6001 0x6001
+#define CMOTECH_PRODUCT_CMU_300 0x6002
+#define CMOTECH_PRODUCT_6003 0x6003
+#define CMOTECH_PRODUCT_6004 0x6004
+#define CMOTECH_PRODUCT_6005 0x6005
+#define CMOTECH_PRODUCT_CGU_628A 0x6006
+#define CMOTECH_PRODUCT_CHE_628S 0x6007
+#define CMOTECH_PRODUCT_CMU_301 0x6008
+#define CMOTECH_PRODUCT_CHU_628 0x6280
+#define CMOTECH_PRODUCT_CHU_628S 0x6281
+#define CMOTECH_PRODUCT_CDU_680 0x6803
+#define CMOTECH_PRODUCT_CDU_685A 0x6804
+#define CMOTECH_PRODUCT_CHU_720S 0x7001
+#define CMOTECH_PRODUCT_7002 0x7002
+#define CMOTECH_PRODUCT_CHU_629K 0x7003
+#define CMOTECH_PRODUCT_7004 0x7004
+#define CMOTECH_PRODUCT_7005 0x7005
+#define CMOTECH_PRODUCT_CGU_629 0x7006
+#define CMOTECH_PRODUCT_CHU_629S 0x700a
+#define CMOTECH_PRODUCT_CHU_720I 0x7211
+#define CMOTECH_PRODUCT_7212 0x7212
+#define CMOTECH_PRODUCT_7213 0x7213
+#define CMOTECH_PRODUCT_7251 0x7251
+#define CMOTECH_PRODUCT_7252 0x7252
+#define CMOTECH_PRODUCT_7253 0x7253
#define TELIT_VENDOR_ID 0x1bc7
#define TELIT_PRODUCT_UC864E 0x1003
#define TELIT_PRODUCT_CC864_DUAL 0x1005
#define TELIT_PRODUCT_CC864_SINGLE 0x1006
#define TELIT_PRODUCT_DE910_DUAL 0x1010
+#define TELIT_PRODUCT_UE910_V2 0x1012
#define TELIT_PRODUCT_LE920 0x1200
/* ZTE PRODUCTS */
#define ALCATEL_PRODUCT_X060S_X200 0x0000
#define ALCATEL_PRODUCT_X220_X500D 0x0017
#define ALCATEL_PRODUCT_L100V 0x011e
+#define ALCATEL_PRODUCT_L800MA 0x0203
#define PIRELLI_VENDOR_ID 0x1266
#define PIRELLI_PRODUCT_C100_1 0x1002
#define OLIVETTI_PRODUCT_OLICARD100 0xc000
#define OLIVETTI_PRODUCT_OLICARD145 0xc003
#define OLIVETTI_PRODUCT_OLICARD200 0xc005
+#define OLIVETTI_PRODUCT_OLICARD500 0xc00b
/* Celot products */
#define CELOT_VENDOR_ID 0x211f
.reserved = BIT(1) | BIT(2),
};
+static const struct option_blacklist_info net_intf0_blacklist = {
+ .reserved = BIT(0),
+};
+
static const struct option_blacklist_info net_intf1_blacklist = {
.reserved = BIT(1),
};
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
- { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
- { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
+ .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6004) },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6005) },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CGU_628A) },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHE_628S),
+ .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_301),
+ .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_628),
+ .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_628S) },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU_680) },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU_685A) },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_720S),
+ .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7002),
+ .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_629K),
+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7004),
+ .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7005) },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CGU_629),
+ .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_629S),
+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_720I),
+ .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7212),
+ .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7213),
+ .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7251),
+ .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7252),
+ .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7253),
+ .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
.driver_info = (kernel_ulong_t)&telit_le920_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
.driver_info = (kernel_ulong_t)&net_intf5_blacklist },
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L800MA),
+ .driver_info = (kernel_ulong_t)&net_intf2_blacklist },
{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
{ USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
{ USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200),
.driver_info = (kernel_ulong_t)&net_intf6_blacklist
},
+ { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD500),
+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist
+ },
{ USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
{ USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) },
{ USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
{ USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LCM960_PRODUCT_ID) },
{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
{ USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
#define SUPERIAL_VENDOR_ID 0x5372
#define SUPERIAL_PRODUCT_ID 0x2303
-/* Hewlett-Packard LD220-HP POS Pole Display */
+/* Hewlett-Packard POS Pole Displays */
#define HP_VENDOR_ID 0x03f0
+#define HP_LD960_PRODUCT_ID 0x0b39
+#define HP_LCM220_PRODUCT_ID 0x3139
+#define HP_LCM960_PRODUCT_ID 0x3239
#define HP_LD220_PRODUCT_ID 0x3524
/* Cressi Edy (diving computer) PC interface */
{USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x68a2, 0)}, /* Sierra Wireless MC7710 Device Management */
{USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x68a2, 2)}, /* Sierra Wireless MC7710 NMEA */
{USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x68a2, 3)}, /* Sierra Wireless MC7710 Modem */
+ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x68c0, 0)}, /* Sierra Wireless MC73xx Device Management */
+ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x68c0, 2)}, /* Sierra Wireless MC73xx NMEA */
+ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x68c0, 3)}, /* Sierra Wireless MC73xx Modem */
{USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 0)}, /* Sierra Wireless EM7700 Device Management */
{USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 2)}, /* Sierra Wireless EM7700 NMEA */
{USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 3)}, /* Sierra Wireless EM7700 Modem */
+ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901f, 0)}, /* Sierra Wireless EM7355 Device Management */
+ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901f, 2)}, /* Sierra Wireless EM7355 NMEA */
+ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901f, 3)}, /* Sierra Wireless EM7355 Modem */
+ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9041, 0)}, /* Sierra Wireless MC7305/MC7355 Device Management */
+ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9041, 2)}, /* Sierra Wireless MC7305/MC7355 NMEA */
+ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9041, 3)}, /* Sierra Wireless MC7305/MC7355 Modem */
{USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 0)}, /* Netgear AirCard 340U Device Management */
{USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 2)}, /* Netgear AirCard 340U NMEA */
{USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 3)}, /* Netgear AirCard 340U Modem */
{ USB_DEVICE(0x0f3d, 0x68A3), /* Airprime/Sierra Wireless Direct IP modems */
.driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
},
- { USB_DEVICE(0x413C, 0x08133) }, /* Dell Computer Corp. Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port */
{ }
};
static void usb_serial_deregister(struct usb_serial_driver *device)
{
pr_info("USB Serial deregistering driver %s\n", device->description);
+
mutex_lock(&table_lock);
list_del(&device->driver_list);
- usb_serial_bus_deregister(device);
mutex_unlock(&table_lock);
+
+ usb_serial_bus_deregister(device);
}
/**
int err;
int i;
+ if (!port->bulk_in_size || !port->bulk_out_size)
+ return -ENODEV;
+
portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
if (!portdata)
return -ENOMEM;
init_usb_anchor(&portdata->delayed);
for (i = 0; i < N_IN_URB; i++) {
- if (!port->bulk_in_size)
- break;
-
buffer = (u8 *)__get_free_page(GFP_KERNEL);
if (!buffer)
goto bail_out_error;
}
for (i = 0; i < N_OUT_URB; i++) {
- if (!port->bulk_out_size)
- break;
-
buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
if (!buffer)
goto bail_out_error2;
if (!(cmdinfo->state & IS_IN_WORK_LIST))
continue;
- err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO);
+ err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
if (!err)
cmdinfo->state &= ~IS_IN_WORK_LIST;
else
devinfo->running_task = 1;
memset(&devinfo->response, 0, sizeof(devinfo->response));
- sense_urb = uas_submit_sense_urb(cmnd, GFP_NOIO,
+ sense_urb = uas_submit_sense_urb(cmnd, GFP_ATOMIC,
devinfo->use_streams ? tag : 0);
if (!sense_urb) {
shost_printk(KERN_INFO, shost,
spin_unlock_irqrestore(&devinfo->lock, flags);
return FAILED;
}
- if (uas_submit_task_urb(cmnd, GFP_NOIO, function, tag)) {
+ if (uas_submit_task_urb(cmnd, GFP_ATOMIC, function, tag)) {
shost_printk(KERN_INFO, shost,
"%s: %s: submit task mgmt urb failed\n",
__func__, fname);
devinfo->use_streams = 0;
} else {
devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1,
- 3, 256, GFP_KERNEL);
+ 3, 256, GFP_NOIO);
if (devinfo->qdepth < 0)
return devinfo->qdepth;
devinfo->use_streams = 1;
eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe);
eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
- usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL);
+ usb_free_streams(devinfo->intf, eps, 3, GFP_NOIO);
}
static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (result)
goto free_streams;
+ usb_set_intfdata(intf, shost);
result = scsi_add_host(shost, &intf->dev);
if (result)
goto free_streams;
scsi_scan_host(shost);
- usb_set_intfdata(intf, shost);
return result;
free_streams:
uas_free_streams(devinfo);
+ usb_set_intfdata(intf, NULL);
set_alt0:
usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
if (shost)
[USB_STATE_RECONNECTING] = "reconnecting",
[USB_STATE_UNAUTHENTICATED] = "unauthenticated",
[USB_STATE_DEFAULT] = "default",
- [USB_STATE_ADDRESS] = "addresssed",
+ [USB_STATE_ADDRESS] = "addressed",
[USB_STATE_CONFIGURED] = "configured",
[USB_STATE_SUSPENDED] = "suspended",
};
if (chid)
result = uwb_radio_start(&wusbhc->pal);
- else
+ else if (wusbhc->uwb_rc)
uwb_radio_stop(&wusbhc->pal);
return result;
done) {
dev_info(dev, "Control EP stall. Queue delayed work.\n");
- spin_lock_irq(&wa->xfer_list_lock);
+ spin_lock(&wa->xfer_list_lock);
/* move xfer from xfer_list to xfer_errored_list. */
list_move_tail(&xfer->list_node, &wa->xfer_errored_list);
- spin_unlock_irq(&wa->xfer_list_lock);
+ spin_unlock(&wa->xfer_list_lock);
spin_unlock_irqrestore(&xfer->lock, flags);
queue_work(wusbd, &wa->xfer_error_work);
} else {
struct uwb_rceb *reply, ssize_t reply_size)
{
struct uwb_rc_evt_set_drp_ie *r = (struct uwb_rc_evt_set_drp_ie *)reply;
+ unsigned long flags;
if (r != NULL) {
if (r->bResultCode != UWB_RC_RES_SUCCESS)
} else
dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: timeout\n");
- spin_lock_irq(&rc->rsvs_lock);
+ spin_lock_irqsave(&rc->rsvs_lock, flags);
if (rc->set_drp_ie_pending > 1) {
rc->set_drp_ie_pending = 0;
- uwb_rsv_queue_update(rc);
+ uwb_rsv_queue_update(rc);
} else {
- rc->set_drp_ie_pending = 0;
+ rc->set_drp_ie_pending = 0;
}
- spin_unlock_irq(&rc->rsvs_lock);
+ spin_unlock_irqrestore(&rc->rsvs_lock, flags);
}
/**
/* alloc and initialize new uwb_cnflt_alien */
cnflt = kzalloc(sizeof(struct uwb_cnflt_alien), GFP_KERNEL);
- if (!cnflt)
+ if (!cnflt) {
dev_err(dev, "failed to alloc uwb_cnflt_alien struct\n");
+ return;
+ }
+
INIT_LIST_HEAD(&cnflt->rc_node);
init_timer(&cnflt->timer);
cnflt->timer.function = uwb_cnflt_timer;
source "drivers/gpu/host1x/Kconfig"
+menu "Direct Rendering Manager"
source "drivers/gpu/drm/Kconfig"
+endmenu
+
+menu "Frame buffer Devices"
+source "drivers/video/fbdev/Kconfig"
+endmenu
+
+source "drivers/video/backlight/Kconfig"
config VGASTATE
tristate
config HDMI
bool
-menuconfig FB
- tristate "Support for frame buffer devices"
- ---help---
- The frame buffer device provides an abstraction for the graphics
- hardware. It represents the frame buffer of some video hardware and
- allows application software to access the graphics hardware through
- a well-defined interface, so the software doesn't need to know
- anything about the low-level (hardware register) stuff.
-
- Frame buffer devices work identically across the different
- architectures supported by Linux and make the implementation of
- application programs easier and more portable; at this point, an X
- server exists which uses the frame buffer device exclusively.
- On several non-X86 architectures, the frame buffer device is the
- only way to use the graphics hardware.
-
- The device is accessed through special device nodes, usually located
- in the /dev directory, i.e. /dev/fb*.
-
- You need an utility program called fbset to make full use of frame
- buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
- and the Framebuffer-HOWTO at
- <http://www.munted.org.uk/programming/Framebuffer-HOWTO-1.3.html> for more
- information.
-
- Say Y here and to the driver for your graphics board below if you
- are compiling a kernel for a non-x86 architecture.
-
- If you are compiling for the x86 architecture, you can say Y if you
- want to play with it, but it is not essential. Please note that
- running graphical applications that directly touch the hardware
- (e.g. an accelerated X server) and that are not frame buffer
- device-aware may cause unexpected results. If unsure, say N.
-
-config FIRMWARE_EDID
- bool "Enable firmware EDID"
- depends on FB
- default n
- ---help---
- This enables access to the EDID transferred from the firmware.
- On the i386, this is from the Video BIOS. Enable this if DDC/I2C
- transfers do not work for your driver and if you are using
- nvidiafb, i810fb or savagefb.
-
- In general, choosing Y for this option is safe. If you
- experience extremely long delays while booting before you get
- something on your display, try setting this to N. Matrox cards in
- combination with certain motherboards and monitors are known to
- suffer from this problem.
-
-config FB_DDC
- tristate
- depends on FB
- select I2C_ALGOBIT
- select I2C
- default n
-
-config FB_BOOT_VESA_SUPPORT
- bool
- depends on FB
- default n
- ---help---
- If true, at least one selected framebuffer driver can take advantage
- of VESA video modes set at an early boot stage via the vga= parameter.
-
-config FB_CFB_FILLRECT
- tristate
- depends on FB
- default n
- ---help---
- Include the cfb_fillrect function for generic software rectangle
- filling. This is used by drivers that don't provide their own
- (accelerated) version.
-
-config FB_CFB_COPYAREA
- tristate
- depends on FB
- default n
- ---help---
- Include the cfb_copyarea function for generic software area copying.
- This is used by drivers that don't provide their own (accelerated)
- version.
-
-config FB_CFB_IMAGEBLIT
- tristate
- depends on FB
- default n
- ---help---
- Include the cfb_imageblit function for generic software image
- blitting. This is used by drivers that don't provide their own
- (accelerated) version.
-
-config FB_CFB_REV_PIXELS_IN_BYTE
- bool
- depends on FB
- default n
- ---help---
- Allow generic frame-buffer functions to work on displays with 1, 2
- and 4 bits per pixel depths which has opposite order of pixels in
- byte order to bytes in long order.
-
-config FB_SYS_FILLRECT
- tristate
- depends on FB
- default n
- ---help---
- Include the sys_fillrect function for generic software rectangle
- filling. This is used by drivers that don't provide their own
- (accelerated) version and the framebuffer is in system RAM.
-
-config FB_SYS_COPYAREA
- tristate
- depends on FB
- default n
- ---help---
- Include the sys_copyarea function for generic software area copying.
- This is used by drivers that don't provide their own (accelerated)
- version and the framebuffer is in system RAM.
-
-config FB_SYS_IMAGEBLIT
- tristate
- depends on FB
- default n
- ---help---
- Include the sys_imageblit function for generic software image
- blitting. This is used by drivers that don't provide their own
- (accelerated) version and the framebuffer is in system RAM.
-
-menuconfig FB_FOREIGN_ENDIAN
- bool "Framebuffer foreign endianness support"
- depends on FB
- ---help---
- This menu will let you enable support for the framebuffers with
- non-native endianness (e.g. Little-Endian framebuffer on a
- Big-Endian machine). Most probably you don't have such hardware,
- so it's safe to say "n" here.
-
-choice
- prompt "Choice endianness support"
- depends on FB_FOREIGN_ENDIAN
-
-config FB_BOTH_ENDIAN
- bool "Support for Big- and Little-Endian framebuffers"
-
-config FB_BIG_ENDIAN
- bool "Support for Big-Endian framebuffers only"
-
-config FB_LITTLE_ENDIAN
- bool "Support for Little-Endian framebuffers only"
-
-endchoice
-
-config FB_SYS_FOPS
- tristate
- depends on FB
- default n
-
-config FB_DEFERRED_IO
- bool
- depends on FB
-
-config FB_HECUBA
- tristate
- depends on FB
- depends on FB_DEFERRED_IO
-
-config FB_SVGALIB
- tristate
- depends on FB
- default n
- ---help---
- Common utility functions useful to fbdev drivers of VGA-based
- cards.
-
-config FB_MACMODES
- tristate
- depends on FB
- default n
-
-config FB_BACKLIGHT
- bool
- depends on FB
- select BACKLIGHT_LCD_SUPPORT
- select BACKLIGHT_CLASS_DEVICE
- default n
-
-config FB_MODE_HELPERS
- bool "Enable Video Mode Handling Helpers"
- depends on FB
- default n
- ---help---
- This enables functions for handling video modes using the
- Generalized Timing Formula and the EDID parser. A few drivers rely
- on this feature such as the radeonfb, rivafb, and the i810fb. If
- your driver does not take advantage of this feature, choosing Y will
- just increase the kernel size by about 5K.
-
-config FB_TILEBLITTING
- bool "Enable Tile Blitting Support"
- depends on FB
- default n
- ---help---
- This enables tile blitting. Tile blitting is a drawing technique
- where the screen is divided into rectangular sections (tiles), whereas
- the standard blitting divides the screen into pixels. Because the
- default drawing element is a tile, drawing functions will be passed
- parameters in terms of number of tiles instead of number of pixels.
- For example, to draw a single character, instead of using bitmaps,
- an index to an array of bitmaps will be used. To clear or move a
- rectangular section of a screen, the rectangle will be described in
- terms of number of tiles in the x- and y-axis.
-
- This is particularly important to one driver, matroxfb. If
- unsure, say N.
-
-comment "Frame buffer hardware drivers"
- depends on FB
-
-config FB_GRVGA
- tristate "Aeroflex Gaisler framebuffer support"
- depends on FB && SPARC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
-
-config FB_CIRRUS
- tristate "Cirrus Logic support"
- depends on FB && (ZORRO || PCI)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- This enables support for Cirrus Logic GD542x/543x based boards on
- Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
-
- If you have a PCI-based system, this enables support for these
- chips: GD-543x, GD-544x, GD-5480.
-
- Please read the file <file:Documentation/fb/cirrusfb.txt>.
-
- Say N unless you have such a graphics board or plan to get one
- before you next recompile the kernel.
-
-config FB_PM2
- tristate "Permedia2 support"
- depends on FB && ((AMIGA && BROKEN) || PCI)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for cards based on
- the 3D Labs Permedia, Permedia 2 and Permedia 2V chips.
- The driver was tested on the following cards:
- Diamond FireGL 1000 PRO AGP
- ELSA Gloria Synergy PCI
- Appian Jeronimo PRO (both heads) PCI
- 3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI
- Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC
- ASK Graphic Blaster Exxtreme AGP
-
- To compile this driver as a module, choose M here: the
- module will be called pm2fb.
-
-config FB_PM2_FIFO_DISCONNECT
- bool "enable FIFO disconnect feature"
- depends on FB_PM2 && PCI
- help
- Support the Permedia2 FIFO disconnect feature.
-
-config FB_ARMCLCD
- tristate "ARM PrimeCell PL110 support"
- depends on ARM || ARM64 || COMPILE_TEST
- depends on FB && ARM_AMBA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This framebuffer device driver is for the ARM PrimeCell PL110
- Colour LCD controller. ARM PrimeCells provide the building
- blocks for System on a Chip devices.
-
- If you want to compile this as a module (=code which can be
- inserted into and removed from the running kernel), say M
- here and read <file:Documentation/kbuild/modules.txt>. The module
- will be called amba-clcd.
-
-config FB_ACORN
- bool "Acorn VIDC support"
- depends on (FB = y) && ARM && ARCH_ACORN
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Acorn VIDC graphics
- hardware found in Acorn RISC PCs and other ARM-based machines. If
- unsure, say N.
-
-config FB_CLPS711X
- bool "CLPS711X LCD support"
- depends on (FB = y) && ARM && ARCH_CLPS711X
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Say Y to enable the Framebuffer driver for the CLPS7111 and
- EP7212 processors.
-
-config FB_SA1100
- bool "SA-1100 LCD support"
- depends on (FB = y) && ARM && ARCH_SA1100
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is a framebuffer device for the SA-1100 LCD Controller.
- See <http://www.linux-fbdev.org/> for information on framebuffer
- devices.
-
- If you plan to use the LCD display with your SA-1100 system, say
- Y here.
-
-config FB_IMX
- tristate "Freescale i.MX1/21/25/27 LCD support"
- depends on FB && ARCH_MXC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MODE_HELPERS
- select VIDEOMODE_HELPERS
-
-config FB_CYBER2000
- tristate "CyberPro 2000/2010/5000 support"
- depends on FB && PCI && (BROKEN || !SPARC64)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This enables support for the Integraphics CyberPro 20x0 and 5000
- VGA chips used in the Rebel.com Netwinder and other machines.
- Say Y if you have a NetWinder or a graphics card containing this
- device, otherwise say N.
-
-config FB_CYBER2000_DDC
- bool "DDC for CyberPro support"
- depends on FB_CYBER2000
- select FB_DDC
- default y
- help
- Say Y here if you want DDC support for your CyberPro graphics
- card. This is only I2C bus support, driver does not use EDID.
-
-config FB_CYBER2000_I2C
- bool "CyberPro 2000/2010/5000 I2C support"
- depends on FB_CYBER2000 && I2C && ARCH_NETWINDER
- select I2C_ALGOBIT
- help
- Enable support for the I2C video decoder interface on the
- Integraphics CyberPro 20x0 and 5000 VGA chips. This is used
- on the Netwinder machines for the SAA7111 video capture.
-
-config FB_APOLLO
- bool
- depends on (FB = y) && APOLLO
- default y
- select FB_CFB_FILLRECT
- select FB_CFB_IMAGEBLIT
-
-config FB_Q40
- bool
- depends on (FB = y) && Q40
- default y
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
-
-config FB_AMIGA
- tristate "Amiga native chipset support"
- depends on FB && AMIGA
- help
- This is the frame buffer device driver for the builtin graphics
- chipset found in Amigas.
-
- To compile this driver as a module, choose M here: the
- module will be called amifb.
-
-config FB_AMIGA_OCS
- bool "Amiga OCS chipset support"
- depends on FB_AMIGA
- help
- This enables support for the original Agnus and Denise video chips,
- found in the Amiga 1000 and most A500's and A2000's. If you intend
- to run Linux on any of these systems, say Y; otherwise say N.
-
-config FB_AMIGA_ECS
- bool "Amiga ECS chipset support"
- depends on FB_AMIGA
- help
- This enables support for the Enhanced Chip Set, found in later
- A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If
- you intend to run Linux on any of these systems, say Y; otherwise
- say N.
-
-config FB_AMIGA_AGA
- bool "Amiga AGA chipset support"
- depends on FB_AMIGA
- help
- This enables support for the Advanced Graphics Architecture (also
- known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T
- and CD32. If you intend to run Linux on any of these systems, say Y;
- otherwise say N.
-
-config FB_FM2
- bool "Amiga FrameMaster II/Rainbow II support"
- depends on (FB = y) && ZORRO
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Amiga FrameMaster
- card from BSC (exhibited 1992 but not shipped as a CBM product).
-
-config FB_ARC
- tristate "Arc Monochrome LCD board support"
- depends on FB && X86
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- help
- This enables support for the Arc Monochrome LCD board. The board
- is based on the KS-108 lcd controller and is typically a matrix
- of 2*n chips. This driver was tested with a 128x64 panel. This
- driver supports it for use with x86 SBCs through a 16 bit GPIO
- interface (8 bit data, 8 bit control). If you anticipate using
- this driver, say Y or M; otherwise say N. You must specify the
- GPIO IO address to be used for setting control and data.
-
-config FB_ATARI
- bool "Atari native chipset support"
- depends on (FB = y) && ATARI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the builtin graphics
- chipset found in Ataris.
-
-config FB_OF
- bool "Open Firmware frame buffer device support"
- depends on (FB = y) && (PPC64 || PPC_OF) && (!PPC_PSERIES || PCI)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES
- help
- Say Y if you want support with Open Firmware for your graphics
- board.
-
-config FB_CONTROL
- bool "Apple \"control\" display support"
- depends on (FB = y) && PPC_PMAC && PPC32
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES
- help
- This driver supports a frame buffer for the graphics adapter in the
- Power Macintosh 7300 and others.
-
-config FB_PLATINUM
- bool "Apple \"platinum\" display support"
- depends on (FB = y) && PPC_PMAC && PPC32
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES
- help
- This driver supports a frame buffer for the "platinum" graphics
- adapter in some Power Macintoshes.
-
-config FB_VALKYRIE
- bool "Apple \"valkyrie\" display support"
- depends on (FB = y) && (MAC || (PPC_PMAC && PPC32))
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES
- help
- This driver supports a frame buffer for the "valkyrie" graphics
- adapter in some Power Macintoshes.
-
-config FB_CT65550
- bool "Chips 65550 display support"
- depends on (FB = y) && PPC32 && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Chips & Technologies
- 65550 graphics chip in PowerBooks.
-
-config FB_ASILIANT
- bool "Asiliant (Chips) 69000 display support"
- depends on (FB = y) && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Asiliant 69030 chipset
-
-config FB_IMSTT
- bool "IMS Twin Turbo display support"
- depends on (FB = y) && PCI
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES if PPC
- help
- The IMS Twin Turbo is a PCI-based frame buffer card bundled with
- many Macintosh and compatible computers.
-
-config FB_VGA16
- tristate "VGA 16-color graphics support"
- depends on FB && (X86 || PPC)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select VGASTATE
- select FONT_8x16 if FRAMEBUFFER_CONSOLE
- help
- This is the frame buffer device driver for VGA 16 color graphic
- cards. Say Y if you have such a card.
-
- To compile this driver as a module, choose M here: the
- module will be called vga16fb.
-
-config FB_BF54X_LQ043
- tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)"
- depends on FB && (BF54x) && !BF542
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD
-
-config FB_BFIN_T350MCQB
- tristate "Varitronix COG-T350MCQB TFT LCD display (BF527 EZKIT)"
- depends on FB && BLACKFIN
- select BFIN_GPTIMERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device driver for a Varitronix VL-PS-COG-T350MCQB-01 display TFT LCD
- This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI
- It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK.
-
-config FB_BFIN_LQ035Q1
- tristate "SHARP LQ035Q1DH02 TFT LCD"
- depends on FB && BLACKFIN && SPI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select BFIN_GPTIMERS
- help
- This is the framebuffer device driver for a SHARP LQ035Q1DH02 TFT display found on
- the Blackfin Landscape LCD EZ-Extender Card.
- This display is a QVGA 320x240 18-bit RGB display interfaced by an 16-bit wide PPI
- It uses PPI[0..15] PPI_FS1, PPI_FS2 and PPI_CLK.
-
- To compile this driver as a module, choose M here: the
- module will be called bfin-lq035q1-fb.
-
-config FB_BF537_LQ035
- tristate "SHARP LQ035 TFT LCD (BF537 STAMP)"
- depends on FB && (BF534 || BF536 || BF537) && I2C_BLACKFIN_TWI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select BFIN_GPTIMERS
- help
- This is the framebuffer device for a SHARP LQ035Q7DB03 TFT LCD
- attached to a BF537.
-
- To compile this driver as a module, choose M here: the
- module will be called bf537-lq035.
-
-config FB_BFIN_7393
- tristate "Blackfin ADV7393 Video encoder"
- depends on FB && BLACKFIN
- select I2C
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for a ADV7393 video encoder
- attached to a Blackfin on the PPI port.
- If your Blackfin board has a ADV7393 select Y.
-
- To compile this driver as a module, choose M here: the
- module will be called bfin_adv7393fb.
-
-choice
- prompt "Video mode support"
- depends on FB_BFIN_7393
- default NTSC
-
-config NTSC
- bool 'NTSC 720x480'
-
-config PAL
- bool 'PAL 720x576'
-
-config NTSC_640x480
- bool 'NTSC 640x480 (Experimental)'
-
-config PAL_640x480
- bool 'PAL 640x480 (Experimental)'
-
-config NTSC_YCBCR
- bool 'NTSC 720x480 YCbCR input'
-
-config PAL_YCBCR
- bool 'PAL 720x576 YCbCR input'
-
-endchoice
-
-choice
- prompt "Size of ADV7393 frame buffer memory Single/Double Size"
- depends on (FB_BFIN_7393)
- default ADV7393_1XMEM
-
-config ADV7393_1XMEM
- bool 'Single'
-
-config ADV7393_2XMEM
- bool 'Double'
-endchoice
-
-config FB_STI
- tristate "HP STI frame buffer device support"
- depends on FB && PARISC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select STI_CONSOLE
- select VT
- default y
- ---help---
- STI refers to the HP "Standard Text Interface" which is a set of
- BIOS routines contained in a ROM chip in HP PA-RISC based machines.
- Enabling this option will implement the linux framebuffer device
- using calls to the STI BIOS routines for initialisation.
-
- If you enable this option, you will get a planar framebuffer device
- /dev/fb which will work on the most common HP graphic cards of the
- NGLE family, including the artist chips (in the 7xx and Bxxx series),
- HCRX, HCRX24, CRX, CRX24 and VisEG series.
-
- It is safe to enable this option, so you should probably say "Y".
-
-config FB_MAC
- bool "Generic Macintosh display support"
- depends on (FB = y) && MAC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES
-
-config FB_HP300
- bool
- depends on (FB = y) && DIO
- select FB_CFB_IMAGEBLIT
- default y
-
-config FB_TGA
- tristate "TGA/SFB+ framebuffer support"
- depends on FB && (ALPHA || TC)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select BITREVERSE
- ---help---
- This is the frame buffer device driver for generic TGA and SFB+
- graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards,
- also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3
- TURBOchannel cards, also known as PMAGD-A, -B and -C.
-
- Due to hardware limitations ZLX-E2 and E3 cards are not supported
- for DECstation 5000/200 systems. Additionally due to firmware
- limitations these cards may cause troubles with booting DECstation
- 5000/240 and /260 systems, but are fully supported under Linux if
- you manage to get it going. ;-)
-
- Say Y if you have one of those.
-
-config FB_UVESA
- tristate "Userspace VESA VGA graphics support"
- depends on FB && CONNECTOR
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MODE_HELPERS
- help
- This is the frame buffer driver for generic VBE 2.0 compliant
- graphic cards. It can also take advantage of VBE 3.0 features,
- such as refresh rate adjustment.
-
- This driver generally provides more features than vesafb but
- requires a userspace helper application called 'v86d'. See
- <file:Documentation/fb/uvesafb.txt> for more information.
-
- If unsure, say N.
-
-config FB_VESA
- bool "VESA VGA graphics support"
- depends on (FB = y) && X86
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_BOOT_VESA_SUPPORT
- help
- This is the frame buffer device driver for generic VESA 2.0
- compliant graphic cards. The older VESA 1.2 cards are not supported.
- You will get a boot time penguin logo at no additional cost. Please
- read <file:Documentation/fb/vesafb.txt>. If unsure, say Y.
-
-config FB_EFI
- bool "EFI-based Framebuffer Support"
- depends on (FB = y) && X86 && EFI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the EFI frame buffer device driver. If the firmware on
- your platform is EFI 1.10 or UEFI 2.0, select Y to add support for
- using the EFI framebuffer as your console.
-
-config FB_N411
- tristate "N411 Apollo/Hecuba devkit support"
- depends on FB && X86 && MMU
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- select FB_HECUBA
- help
- This enables support for the Apollo display controller in its
- Hecuba form using the n411 devkit.
-
-config FB_HGA
- tristate "Hercules mono graphics support"
- depends on FB && X86
- help
- Say Y here if you have a Hercules mono graphics card.
-
- To compile this driver as a module, choose M here: the
- module will be called hgafb.
-
- As this card technology is at least 25 years old,
- most people will answer N here.
-
-config FB_GBE
- bool "SGI Graphics Backend frame buffer support"
- depends on (FB = y) && SGI_IP32
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for SGI Graphics Backend.
- This chip is used in SGI O2 and Visual Workstation 320/540.
-
-config FB_GBE_MEM
- int "Video memory size in MB"
- depends on FB_GBE
- default 4
- help
- This is the amount of memory reserved for the framebuffer,
- which can be any value between 1MB and 8MB.
-
-config FB_SBUS
- bool "SBUS and UPA framebuffers"
- depends on (FB = y) && SPARC
- help
- Say Y if you want support for SBUS or UPA based frame buffer device.
-
-config FB_BW2
- bool "BWtwo support"
- depends on (FB = y) && (SPARC && FB_SBUS)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the BWtwo frame buffer.
-
-config FB_CG3
- bool "CGthree support"
- depends on (FB = y) && (SPARC && FB_SBUS)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the CGthree frame buffer.
-
-config FB_CG6
- bool "CGsix (GX,TurboGX) support"
- depends on (FB = y) && (SPARC && FB_SBUS)
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the CGsix (GX, TurboGX)
- frame buffer.
-
-config FB_FFB
- bool "Creator/Creator3D/Elite3D support"
- depends on FB_SBUS && SPARC64
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Creator, Creator3D,
- and Elite3D graphics boards.
-
-config FB_TCX
- bool "TCX (SS4/SS5 only) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the TCX 24/8bit frame
- buffer.
-
-config FB_CG14
- bool "CGfourteen (SX) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the CGfourteen frame
- buffer on Desktop SPARCsystems with the SX graphics option.
-
-config FB_P9100
- bool "P9100 (Sparcbook 3 only) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the P9100 card
- supported on Sparcbook 3 machines.
-
-config FB_LEO
- bool "Leo (ZX) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the SBUS-based Sun ZX
- (leo) frame buffer cards.
-
-config FB_IGA
- bool "IGA 168x display support"
- depends on (FB = y) && SPARC32
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the INTERGRAPHICS 1680 and
- successor frame buffer cards.
-
-config FB_XVR500
- bool "Sun XVR-500 3DLABS Wildcat support"
- depends on (FB = y) && PCI && SPARC64
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the Sun XVR-500 and similar
- graphics cards based upon the 3DLABS Wildcat chipset. The driver
- only works on sparc64 systems where the system firmware has
- mostly initialized the card already. It is treated as a
- completely dumb framebuffer device.
-
-config FB_XVR2500
- bool "Sun XVR-2500 3DLABS Wildcat support"
- depends on (FB = y) && PCI && SPARC64
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the Sun XVR-2500 and similar
- graphics cards based upon the 3DLABS Wildcat chipset. The driver
- only works on sparc64 systems where the system firmware has
- mostly initialized the card already. It is treated as a
- completely dumb framebuffer device.
-
-config FB_XVR1000
- bool "Sun XVR-1000 support"
- depends on (FB = y) && SPARC64
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the Sun XVR-1000 and similar
- graphics cards. The driver only works on sparc64 systems where
- the system firmware has mostly initialized the card already. It
- is treated as a completely dumb framebuffer device.
-
-config FB_PVR2
- tristate "NEC PowerVR 2 display support"
- depends on FB && SH_DREAMCAST
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Say Y here if you have a PowerVR 2 card in your box. If you plan to
- run linux on your Dreamcast, you will have to say Y here.
- This driver may or may not work on other PowerVR 2 cards, but is
- totally untested. Use at your own risk. If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called pvr2fb.
-
- You can pass several parameters to the driver at boot time or at
- module load time. The parameters look like "video=pvr2:XXX", where
- the meaning of XXX can be found at the end of the main source file
- (<file:drivers/video/pvr2fb.c>). Please see the file
- <file:Documentation/fb/pvr2fb.txt>.
-
-config FB_OPENCORES
- tristate "OpenCores VGA/LCD core 2.0 framebuffer support"
- depends on FB && HAS_DMA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This enables support for the OpenCores VGA/LCD core.
-
- The OpenCores VGA/LCD core is typically used together with
- softcore CPUs (e.g. OpenRISC or Microblaze) or hard processor
- systems (e.g. Altera socfpga or Xilinx Zynq) on FPGAs.
-
- The source code and specification for the core is available at
- <http://opencores.org/project,vga_lcd>
-
-config FB_S1D13XXX
- tristate "Epson S1D13XXX framebuffer support"
- depends on FB
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Support for S1D13XXX framebuffer device family (currently only
- working with S1D13806). Product specs at
- <http://vdc.epson.com/>
-
-config FB_ATMEL
- tristate "AT91/AT32 LCD Controller support"
- depends on FB && HAVE_FB_ATMEL
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MODE_HELPERS
- select VIDEOMODE_HELPERS
- help
- This enables support for the AT91/AT32 LCD Controller.
-
-config FB_INTSRAM
- bool "Frame Buffer in internal SRAM"
- depends on FB_ATMEL && ARCH_AT91SAM9261
- help
- Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want
- to let frame buffer in external SDRAM.
-
-config FB_ATMEL_STN
- bool "Use a STN display with AT91/AT32 LCD Controller"
- depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK)
- default n
- help
- Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD
- Controller. Say N if you want to connect a TFT.
-
- If unsure, say N.
-
-config FB_NVIDIA
- tristate "nVidia Framebuffer Support"
- depends on FB && PCI
- select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select BITREVERSE
- select VGASTATE
- help
- This driver supports graphics boards with the nVidia chips, TNT
- and newer. For very old chipsets, such as the RIVA128, then use
- the rivafb.
- Say Y if you have such a graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called nvidiafb.
-
-config FB_NVIDIA_I2C
- bool "Enable DDC Support"
- depends on FB_NVIDIA
- select FB_DDC
- help
- This enables I2C support for nVidia Chipsets. This is used
- only for getting EDID information from the attached display
- allowing for robust video mode handling and switching.
-
- Because fbdev-2.6 requires that drivers must be able to
- independently validate video mode parameters, you should say Y
- here.
-
-config FB_NVIDIA_DEBUG
- bool "Lots of debug output"
- depends on FB_NVIDIA
- default n
- help
- Say Y here if you want the nVidia driver to output all sorts
- of debugging information to provide to the maintainer when
- something goes wrong.
-
-config FB_NVIDIA_BACKLIGHT
- bool "Support for backlight control"
- depends on FB_NVIDIA
- default y
- help
- Say Y here if you want to control the backlight of your display.
-
-config FB_RIVA
- tristate "nVidia Riva support"
- depends on FB && PCI
- select FB_BACKLIGHT if FB_RIVA_BACKLIGHT
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select BITREVERSE
- select VGASTATE
- help
- This driver supports graphics boards with the nVidia Riva/Geforce
- chips.
- Say Y if you have such a graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called rivafb.
-
-config FB_RIVA_I2C
- bool "Enable DDC Support"
- depends on FB_RIVA
- select FB_DDC
- help
- This enables I2C support for nVidia Chipsets. This is used
- only for getting EDID information from the attached display
- allowing for robust video mode handling and switching.
-
- Because fbdev-2.6 requires that drivers must be able to
- independently validate video mode parameters, you should say Y
- here.
-
-config FB_RIVA_DEBUG
- bool "Lots of debug output"
- depends on FB_RIVA
- default n
- help
- Say Y here if you want the Riva driver to output all sorts
- of debugging information to provide to the maintainer when
- something goes wrong.
-
-config FB_RIVA_BACKLIGHT
- bool "Support for backlight control"
- depends on FB_RIVA
- default y
- help
- Say Y here if you want to control the backlight of your display.
-
-config FB_I740
- tristate "Intel740 support"
- depends on FB && PCI
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select VGASTATE
- select FB_DDC
- help
- This driver supports graphics cards based on Intel740 chip.
-
-config FB_I810
- tristate "Intel 810/815 support"
- depends on FB && PCI && X86_32 && AGP_INTEL
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select VGASTATE
- help
- This driver supports the on-board graphics built in to the Intel 810
- and 815 chipsets. Say Y if you have and plan to use such a board.
-
- To compile this driver as a module, choose M here: the
- module will be called i810fb.
-
- For more information, please read
- <file:Documentation/fb/intel810.txt>
-
-config FB_I810_GTF
- bool "use VESA Generalized Timing Formula"
- depends on FB_I810
- help
- If you say Y, then the VESA standard, Generalized Timing Formula
- or GTF, will be used to calculate the required video timing values
- per video mode. Since the GTF allows nondiscrete timings
- (nondiscrete being a range of values as opposed to discrete being a
- set of values), you'll be able to use any combination of horizontal
- and vertical resolutions, and vertical refresh rates without having
- to specify your own timing parameters. This is especially useful
- to maximize the performance of an aging display, or if you just
- have a display with nonstandard dimensions. A VESA compliant
- monitor is recommended, but can still work with non-compliant ones.
- If you need or want this, then select this option. The timings may
- not be compliant with Intel's recommended values. Use at your own
- risk.
-
- If you say N, the driver will revert to discrete video timings
- using a set recommended by Intel in their documentation.
-
- If unsure, say N.
-
-config FB_I810_I2C
- bool "Enable DDC Support"
- depends on FB_I810 && FB_I810_GTF
- select FB_DDC
- help
-
-config FB_LE80578
- tristate "Intel LE80578 (Vermilion) support"
- depends on FB && PCI && X86
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This driver supports the LE80578 (Vermilion Range) chipset
-
-config FB_CARILLO_RANCH
- tristate "Intel Carillo Ranch support"
- depends on FB_LE80578 && FB && PCI && X86
- help
- This driver supports the LE80578 (Carillo Ranch) board
-
-config FB_INTEL
- tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support"
- depends on FB && PCI && X86 && AGP_INTEL && EXPERT
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_BOOT_VESA_SUPPORT if FB_INTEL = y
- depends on !DRM_I915
- help
- This driver supports the on-board graphics built in to the Intel
- 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
- Say Y if you have and plan to use such a board.
-
- To make FB_INTELFB=Y work you need to say AGP_INTEL=y too.
-
- To compile this driver as a module, choose M here: the
- module will be called intelfb.
-
- For more information, please read <file:Documentation/fb/intelfb.txt>
-
-config FB_INTEL_DEBUG
- bool "Intel driver Debug Messages"
- depends on FB_INTEL
- ---help---
- Say Y here if you want the Intel driver to output all sorts
- of debugging information to provide to the maintainer when
- something goes wrong.
-
-config FB_INTEL_I2C
- bool "DDC/I2C for Intel framebuffer support"
- depends on FB_INTEL
- select FB_DDC
- default y
- help
- Say Y here if you want DDC/I2C support for your on-board Intel graphics.
-
-config FB_MATROX
- tristate "Matrox acceleration"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_TILEBLITTING
- select FB_MACMODES if PPC_PMAC
- ---help---
- Say Y here if you have a Matrox Millennium, Matrox Millennium II,
- Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
- Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video,
- Matrox G400, G450 or G550 card in your box.
-
- To compile this driver as a module, choose M here: the
- module will be called matroxfb.
-
- You can pass several parameters to the driver at boot time or at
- module load time. The parameters look like "video=matroxfb:XXX", and
- are described in <file:Documentation/fb/matroxfb.txt>.
-
-config FB_MATROX_MILLENIUM
- bool "Millennium I/II support"
- depends on FB_MATROX
- help
- Say Y here if you have a Matrox Millennium or Matrox Millennium II
- video card. If you select "Advanced lowlevel driver options" below,
- you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp
- packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can
- also use font widths different from 8.
-
-config FB_MATROX_MYSTIQUE
- bool "Mystique support"
- depends on FB_MATROX
- help
- Say Y here if you have a Matrox Mystique or Matrox Mystique 220
- video card. If you select "Advanced lowlevel driver options" below,
- you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp
- packed pixel and 32 bpp packed pixel. You can also use font widths
- different from 8.
-
-config FB_MATROX_G
- bool "G100/G200/G400/G450/G550 support"
- depends on FB_MATROX
- ---help---
- Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based
- video card. If you select "Advanced lowlevel driver options", you
- should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
- pixel and 32 bpp packed pixel. You can also use font widths
- different from 8.
-
- If you need support for G400 secondary head, you must say Y to
- "Matrox I2C support" and "G400 second head support" right below.
- G450/G550 secondary head and digital output are supported without
- additional modules.
-
- The driver starts in monitor mode. You must use the matroxset tool
- (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to
- swap primary and secondary head outputs, or to change output mode.
- Secondary head driver always start in 640x480 resolution and you
- must use fbset to change it.
-
- Do not forget that second head supports only 16 and 32 bpp
- packed pixels, so it is a good idea to compile them into the kernel
- too. You can use only some font widths, as the driver uses generic
- painting procedures (the secondary head does not use acceleration
- engine).
-
- G450/G550 hardware can display TV picture only from secondary CRTC,
- and it performs no scaling, so picture must have 525 or 625 lines.
-
-config FB_MATROX_I2C
- tristate "Matrox I2C support"
- depends on FB_MATROX
- select FB_DDC
- ---help---
- This drivers creates I2C buses which are needed for accessing the
- DDC (I2C) bus present on all Matroxes, an I2C bus which
- interconnects Matrox optional devices, like MGA-TVO on G200 and
- G400, and the secondary head DDC bus, present on G400 only.
-
- You can say Y or M here if you want to experiment with monitor
- detection code. You must say Y or M here if you want to use either
- second head of G400 or MGA-TVO on G200 or G400.
-
- If you compile it as module, it will create a module named
- i2c-matroxfb.
-
-config FB_MATROX_MAVEN
- tristate "G400 second head support"
- depends on FB_MATROX_G && FB_MATROX_I2C
- ---help---
- WARNING !!! This support does not work with G450 !!!
-
- Say Y or M here if you want to use a secondary head (meaning two
- monitors in parallel) on G400 or MGA-TVO add-on on G200. Secondary
- head is not compatible with accelerated XFree 3.3.x SVGA servers -
- secondary head output is blanked while you are in X. With XFree
- 3.9.17 preview you can use both heads if you use SVGA over fbdev or
- the fbdev driver on first head and the fbdev driver on second head.
-
- If you compile it as module, two modules are created,
- matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for
- both G200 and G400, matroxfb_crtc2 is needed only by G400. You must
- also load i2c-matroxfb to get it to run.
-
- The driver starts in monitor mode and you must use the matroxset
- tool (available at
- <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to switch it to
- PAL or NTSC or to swap primary and secondary head outputs.
- Secondary head driver also always start in 640x480 resolution, you
- must use fbset to change it.
-
- Also do not forget that second head supports only 16 and 32 bpp
- packed pixels, so it is a good idea to compile them into the kernel
- too. You can use only some font widths, as the driver uses generic
- painting procedures (the secondary head does not use acceleration
- engine).
-
-config FB_RADEON
- tristate "ATI Radeon display support"
- depends on FB && PCI
- select FB_BACKLIGHT if FB_RADEON_BACKLIGHT
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES if PPC_OF
- help
- Choose this option if you want to use an ATI Radeon graphics card as
- a framebuffer device. There are both PCI and AGP versions. You
- don't need to choose this to run the Radeon in plain VGA mode.
-
- There is a product page at
- http://products.amd.com/en-us/GraphicCardResult.aspx
-
-config FB_RADEON_I2C
- bool "DDC/I2C for ATI Radeon support"
- depends on FB_RADEON
- select FB_DDC
- default y
- help
- Say Y here if you want DDC/I2C support for your Radeon board.
-
-config FB_RADEON_BACKLIGHT
- bool "Support for backlight control"
- depends on FB_RADEON
- default y
- help
- Say Y here if you want to control the backlight of your display.
-
-config FB_RADEON_DEBUG
- bool "Lots of debug output from Radeon driver"
- depends on FB_RADEON
- default n
- help
- Say Y here if you want the Radeon driver to output all sorts
- of debugging information to provide to the maintainer when
- something goes wrong.
-
-config FB_ATY128
- tristate "ATI Rage128 display support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_BACKLIGHT if FB_ATY128_BACKLIGHT
- select FB_MACMODES if PPC_PMAC
- help
- This driver supports graphics boards with the ATI Rage128 chips.
- Say Y if you have such a graphics board and read
- <file:Documentation/fb/aty128fb.txt>.
-
- To compile this driver as a module, choose M here: the
- module will be called aty128fb.
-
-config FB_ATY128_BACKLIGHT
- bool "Support for backlight control"
- depends on FB_ATY128
- default y
- help
- Say Y here if you want to control the backlight of your display.
-
-config FB_ATY
- tristate "ATI Mach64 display support" if PCI || ATARI
- depends on FB && !SPARC32
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_BACKLIGHT if FB_ATY_BACKLIGHT
- select FB_MACMODES if PPC
- help
- This driver supports graphics boards with the ATI Mach64 chips.
- Say Y if you have such a graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called atyfb.
-
-config FB_ATY_CT
- bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
- depends on PCI && FB_ATY
- default y if SPARC64 && PCI
- help
- Say Y here to support use of ATI's 64-bit Rage boards (or other
- boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
- framebuffer device. The ATI product support page for these boards
- is at <http://support.ati.com/products/pc/mach64/mach64.html>.
-
-config FB_ATY_GENERIC_LCD
- bool "Mach64 generic LCD support"
- depends on FB_ATY_CT
- help
- Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility,
- Rage XC, or Rage XL chipset.
-
-config FB_ATY_GX
- bool "Mach64 GX support" if PCI
- depends on FB_ATY
- default y if ATARI
- help
- Say Y here to support use of the ATI Mach64 Graphics Expression
- board (or other boards based on the Mach64 GX chipset) as a
- framebuffer device. The ATI product support page for these boards
- is at
- <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
-
-config FB_ATY_BACKLIGHT
- bool "Support for backlight control"
- depends on FB_ATY
- default y
- help
- Say Y here if you want to control the backlight of your display.
-
-config FB_S3
- tristate "S3 Trio/Virge support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_TILEBLITTING
- select FB_SVGALIB
- select VGASTATE
- select FONT_8x16 if FRAMEBUFFER_CONSOLE
- ---help---
- Driver for graphics boards with S3 Trio / S3 Virge chip.
-
-config FB_S3_DDC
- bool "DDC for S3 support"
- depends on FB_S3
- select FB_DDC
- default y
- help
- Say Y here if you want DDC support for your S3 graphics card.
-
-config FB_SAVAGE
- tristate "S3 Savage support"
- depends on FB && PCI
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select VGASTATE
- help
- This driver supports notebooks and computers with S3 Savage PCI/AGP
- chips.
-
- Say Y if you have such a graphics card.
-
- To compile this driver as a module, choose M here; the module
- will be called savagefb.
-
-config FB_SAVAGE_I2C
- bool "Enable DDC2 Support"
- depends on FB_SAVAGE
- select FB_DDC
- help
- This enables I2C support for S3 Savage Chipsets. This is used
- only for getting EDID information from the attached display
- allowing for robust video mode handling and switching.
-
- Because fbdev-2.6 requires that drivers must be able to
- independently validate video mode parameters, you should say Y
- here.
-
-config FB_SAVAGE_ACCEL
- bool "Enable Console Acceleration"
- depends on FB_SAVAGE
- default n
- help
- This option will compile in console acceleration support. If
- the resulting framebuffer console has bothersome glitches, then
- choose N here.
-
-config FB_SIS
- tristate "SiS/XGI display support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_BOOT_VESA_SUPPORT if FB_SIS = y
- help
- This is the frame buffer device driver for the SiS 300, 315, 330
- and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
- Specs available at <http://www.sis.com> and <http://www.xgitech.com>.
-
- To compile this driver as a module, choose M here; the module
- will be called sisfb.
-
-config FB_SIS_300
- bool "SiS 300 series support"
- depends on FB_SIS
- help
- Say Y here to support use of the SiS 300/305, 540, 630 and 730.
-
-config FB_SIS_315
- bool "SiS 315/330/340 series and XGI support"
- depends on FB_SIS
- help
- Say Y here to support use of the SiS 315, 330 and 340 series
- (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
- as XGI V3XT, V5, V8 and Z7.
-
-config FB_VIA
- tristate "VIA UniChrome (Pro) and Chrome9 display support"
- depends on FB && PCI && X86
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select I2C_ALGOBIT
- select I2C
- select GPIOLIB
- help
- This is the frame buffer device driver for Graphics chips of VIA
- UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
- CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896
- /P4M900,VX800)
- Say Y if you have a VIA UniChrome graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called viafb.
-
-if FB_VIA
-
-config FB_VIA_DIRECT_PROCFS
- bool "direct hardware access via procfs (DEPRECATED)(DANGEROUS)"
- depends on FB_VIA
- default n
- help
- Allow direct hardware access to some output registers via procfs.
- This is dangerous but may provide the only chance to get the
- correct output device configuration.
- Its use is strongly discouraged.
-
-config FB_VIA_X_COMPATIBILITY
- bool "X server compatibility"
- depends on FB_VIA
- default n
- help
- This option reduces the functionality (power saving, ...) of the
- framebuffer to avoid negative impact on the OpenChrome X server.
- If you use any X server other than fbdev you should enable this
- otherwise it should be safe to disable it and allow using all
- features.
-
-endif
-
-config FB_NEOMAGIC
- tristate "NeoMagic display support"
- depends on FB && PCI
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select VGASTATE
- help
- This driver supports notebooks with NeoMagic PCI chips.
- Say Y if you have such a graphics card.
-
- To compile this driver as a module, choose M here: the
- module will be called neofb.
-
-config FB_KYRO
- tristate "IMG Kyro support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Say Y here if you have a STG4000 / Kyro / PowerVR 3 based
- graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called kyrofb.
-
-config FB_3DFX
- tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support"
- depends on FB && PCI
- select FB_CFB_IMAGEBLIT
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_MODE_HELPERS
- help
- This driver supports graphics boards with the 3Dfx Banshee,
- Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have
- such a graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called tdfxfb.
-
-config FB_3DFX_ACCEL
- bool "3Dfx Acceleration functions"
- depends on FB_3DFX
- ---help---
- This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
- device driver with acceleration functions.
-
-config FB_3DFX_I2C
- bool "Enable DDC/I2C support"
- depends on FB_3DFX
- select FB_DDC
- default y
- help
- Say Y here if you want DDC/I2C support for your 3dfx Voodoo3.
-
-config FB_VOODOO1
- tristate "3Dfx Voodoo Graphics (sst1) support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
- Voodoo2 (cvg) based graphics card.
-
- To compile this driver as a module, choose M here: the
- module will be called sstfb.
-
- WARNING: Do not use any application that uses the 3D engine
- (namely glide) while using this driver.
- Please read the <file:Documentation/fb/sstfb.txt> for supported
- options and other important info support.
-
-config FB_VT8623
- tristate "VIA VT8623 support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_TILEBLITTING
- select FB_SVGALIB
- select VGASTATE
- select FONT_8x16 if FRAMEBUFFER_CONSOLE
- ---help---
- Driver for CastleRock integrated graphics core in the
- VIA VT8623 [Apollo CLE266] chipset.
-
-config FB_TRIDENT
- tristate "Trident/CyberXXX/CyberBlade support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- This is the frame buffer device driver for Trident PCI/AGP chipsets.
- Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D
- and Blade XP.
- There are also integrated versions of these chips called CyberXXXX,
- CyberImage or CyberBlade. These chips are mostly found in laptops
- but also on some motherboards including early VIA EPIA motherboards.
- For more information, read <file:Documentation/fb/tridentfb.txt>
-
- Say Y if you have such a graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called tridentfb.
-
-config FB_ARK
- tristate "ARK 2000PV support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_TILEBLITTING
- select FB_SVGALIB
- select VGASTATE
- select FONT_8x16 if FRAMEBUFFER_CONSOLE
- ---help---
- Driver for PCI graphics boards with ARK 2000PV chip
- and ICS 5342 RAMDAC.
-
-config FB_PM3
- tristate "Permedia3 support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the 3DLabs Permedia3
- chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
- similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
- and maybe other boards.
-
-config FB_CARMINE
- tristate "Fujitsu carmine frame buffer support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Fujitsu Carmine chip.
- The driver provides two independent frame buffer devices.
-
-choice
- depends on FB_CARMINE
- prompt "DRAM timing"
- default FB_CARMINE_DRAM_EVAL
-
-config FB_CARMINE_DRAM_EVAL
- bool "Eval board timings"
- help
- Use timings which work on the eval card.
-
-config CARMINE_DRAM_CUSTOM
- bool "Custom board timings"
- help
- Use custom board timings.
-endchoice
-
-config FB_AU1100
- bool "Au1100 LCD Driver"
- depends on (FB = y) && MIPS_ALCHEMY
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer driver for the AMD Au1100 SOC. It can drive
- various panels and CRTs by passing in kernel cmd line option
- au1100fb:panel=<name>.
-
-config FB_AU1200
- bool "Au1200/Au1300 LCD Driver"
- depends on (FB = y) && MIPS_ALCHEMY
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- help
- This is the framebuffer driver for the Au1200/Au1300 SOCs.
- It can drive various panels and CRTs by passing in kernel cmd line
- option au1200fb:panel=<name>.
-
-config FB_VT8500
- bool "VIA VT8500 framebuffer support"
- depends on (FB = y) && ARM && ARCH_VT8500
- select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
- select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
- select FB_SYS_IMAGEBLIT
- select FB_MODE_HELPERS
- select VIDEOMODE_HELPERS
- help
- This is the framebuffer driver for VIA VT8500 integrated LCD
- controller.
-
-config FB_WM8505
- bool "Wondermedia WM8xxx-series frame buffer support"
- depends on (FB = y) && ARM && ARCH_VT8500
- select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
- select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
- select FB_SYS_IMAGEBLIT
- select FB_MODE_HELPERS
- select VIDEOMODE_HELPERS
- help
- This is the framebuffer driver for WonderMedia WM8xxx-series
- integrated LCD controller. This driver covers the WM8505, WM8650
- and WM8850 SoCs.
-
-config FB_WMT_GE_ROPS
- bool "VT8500/WM8xxx accelerated raster ops support"
- depends on (FB = y) && (FB_VT8500 || FB_WM8505)
- default n
- help
- This adds support for accelerated raster operations on the
- VIA VT8500 and Wondermedia 85xx series SoCs.
-
-source "drivers/video/geode/Kconfig"
-
-config FB_HIT
- tristate "HD64461 Frame Buffer support"
- depends on FB && HD64461
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Hitachi HD64461 LCD
- frame buffer card.
-
-config FB_PMAG_AA
- bool "PMAG-AA TURBOchannel framebuffer support"
- depends on (FB = y) && TC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
- used mainly in the MIPS-based DECstation series.
-
-config FB_PMAG_BA
- tristate "PMAG-BA TURBOchannel framebuffer support"
- depends on FB && TC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
- used mainly in the MIPS-based DECstation series.
-
-config FB_PMAGB_B
- tristate "PMAGB-B TURBOchannel framebuffer support"
- depends on FB && TC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Support for the PMAGB-B TURBOchannel framebuffer card used mainly
- in the MIPS-based DECstation series. The card is currently only
- supported in 1280x1024x8 mode.
-
-config FB_MAXINE
- bool "Maxine (Personal DECstation) onboard framebuffer support"
- depends on (FB = y) && MACH_DECSTATION
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Support for the onboard framebuffer (1024x768x8) in the Personal
- DECstation series (Personal DECstation 5000/20, /25, /33, /50,
- Codename "Maxine").
-
-config FB_G364
- bool "G364 frame buffer support"
- depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- The G364 driver is the framebuffer used in MIPS Magnum 4000 and
- Olivetti M700-10 systems.
-
-config FB_68328
- bool "Motorola 68328 native frame buffer support"
- depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Say Y here if you want to support the built-in frame buffer of
- the Motorola 68328 CPU family.
-
-config FB_PXA168
- tristate "PXA168/910 LCD framebuffer support"
- depends on FB && (CPU_PXA168 || CPU_PXA910)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the built-in LCD controller in the Marvell
- MMP processor.
-
-config FB_PXA
- tristate "PXA LCD framebuffer support"
- depends on FB && ARCH_PXA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the built-in LCD controller in the Intel
- PXA2x0 processor.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called pxafb. If you want to compile it as a module,
- say M here and read <file:Documentation/kbuild/modules.txt>.
-
- If unsure, say N.
-
-config FB_PXA_OVERLAY
- bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer"
- default n
- depends on FB_PXA && (PXA27x || PXA3xx)
-
-config FB_PXA_SMARTPANEL
- bool "PXA Smartpanel LCD support"
- default n
- depends on FB_PXA
-
-config FB_PXA_PARAMETERS
- bool "PXA LCD command line parameters"
- default n
- depends on FB_PXA
- ---help---
- Enable the use of kernel command line or module parameters
- to configure the physical properties of the LCD panel when
- using the PXA LCD driver.
-
- This option allows you to override the panel parameters
- supplied by the platform in order to support multiple
- different models of flatpanel. If you will only be using a
- single model of flatpanel then you can safely leave this
- option disabled.
-
- <file:Documentation/fb/pxafb.txt> describes the available parameters.
-
-config PXA3XX_GCU
- tristate "PXA3xx 2D graphics accelerator driver"
- depends on FB_PXA
- help
- Kernelspace driver for the 2D graphics controller unit (GCU)
- found on PXA3xx processors. There is a counterpart driver in the
- DirectFB suite, see http://www.directfb.org/
-
- If you compile this as a module, it will be called pxa3xx_gcu.
-
-config FB_MBX
- tristate "2700G LCD framebuffer support"
- depends on FB && ARCH_PXA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Framebuffer driver for the Intel 2700G (Marathon) Graphics
- Accelerator
-
-config FB_MBX_DEBUG
- bool "Enable debugging info via debugfs"
- depends on FB_MBX && DEBUG_FS
- default n
- ---help---
- Enable this if you want debugging information using the debug
- filesystem (debugfs)
-
- If unsure, say N.
-
-config FB_FSL_DIU
- tristate "Freescale DIU framebuffer support"
- depends on FB && FSL_SOC
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select PPC_LIB_RHEAP
- ---help---
- Framebuffer driver for the Freescale SoC DIU
-
-config FB_W100
- tristate "W100 frame buffer support"
- depends on FB && ARCH_PXA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
- It can also drive the w3220 chip found on iPAQ hx4700.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called w100fb. If you want to compile it as a module,
- say M here and read <file:Documentation/kbuild/modules.txt>.
-
- If unsure, say N.
-
-config FB_SH_MOBILE_LCDC
- tristate "SuperH Mobile LCDC framebuffer support"
- depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- select FB_BACKLIGHT
- select SH_MIPI_DSI if SH_LCD_MIPI_DSI
- ---help---
- Frame buffer driver for the on-chip SH-Mobile LCD controller.
-
-config FB_SH_MOBILE_HDMI
- tristate "SuperH Mobile HDMI controller support"
- depends on FB_SH_MOBILE_LCDC
- select FB_MODE_HELPERS
- select SOUND
- select SND
- select SND_SOC
- ---help---
- Driver for the on-chip SH-Mobile HDMI controller.
-
-config FB_TMIO
- tristate "Toshiba Mobile IO FrameBuffer support"
- depends on FB && MFD_CORE
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the Toshiba Mobile IO integrated as found
- on the Sharp SL-6000 series
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called tmiofb. If you want to compile it as a module,
- say M here and read <file:Documentation/kbuild/modules.txt>.
-
- If unsure, say N.
-
-config FB_TMIO_ACCELL
- bool "tmiofb acceleration"
- depends on FB_TMIO
- default y
-
-config FB_S3C
- tristate "Samsung S3C framebuffer support"
- depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \
- ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the built-in FB controller in the Samsung
- SoC line from the S3C2443 onwards, including the S3C2416, S3C2450,
- and the S3C64XX series such as the S3C6400 and S3C6410.
-
- These chips all have the same basic framebuffer design with the
- actual capabilities depending on the chip. For instance the S3C6400
- and S3C6410 support 4 hardware windows whereas the S3C24XX series
- currently only have two.
-
- Currently the support is only for the S3C6400 and S3C6410 SoCs.
-
-config FB_S3C_DEBUG_REGWRITE
- bool "Debug register writes"
- depends on FB_S3C
- ---help---
- Show all register writes via pr_debug()
-
-config FB_S3C2410
- tristate "S3C2410 LCD framebuffer support"
- depends on FB && ARCH_S3C24XX
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the built-in LCD controller in the Samsung
- S3C2410 processor.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called s3c2410fb. If you want to compile it as a module,
- say M here and read <file:Documentation/kbuild/modules.txt>.
-
- If unsure, say N.
-config FB_S3C2410_DEBUG
- bool "S3C2410 lcd debug messages"
- depends on FB_S3C2410
- help
- Turn on debugging messages. Note that you can set/unset at run time
- through sysfs
-
-config FB_NUC900
- bool "NUC900 LCD framebuffer support"
- depends on FB && ARCH_W90X900
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the built-in LCD controller in the Nuvoton
- NUC900 processor
-
-config GPM1040A0_320X240
- bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD"
- depends on FB_NUC900
-
-config FB_SM501
- tristate "Silicon Motion SM501 framebuffer support"
- depends on FB && MFD_SM501
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the CRT and LCD controllers in the Silicon
- Motion SM501.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called sm501fb. If you want to compile it as a module,
- say M here and read <file:Documentation/kbuild/modules.txt>.
-
- If unsure, say N.
-
-config FB_SMSCUFX
- tristate "SMSC UFX6000/7000 USB Framebuffer support"
- depends on FB && USB
- select FB_MODE_HELPERS
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- ---help---
- This is a kernel framebuffer driver for SMSC UFX USB devices.
- Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
- mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000
- (USB 3.0) devices.
- To compile as a module, choose M here: the module name is smscufx.
-
-config FB_UDL
- tristate "Displaylink USB Framebuffer support"
- depends on FB && USB
- select FB_MODE_HELPERS
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- ---help---
- This is a kernel framebuffer driver for DisplayLink USB devices.
- Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
- mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
- To compile as a module, choose M here: the module name is udlfb.
-
-config FB_IBM_GXT4500
- tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors"
- depends on FB && PPC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Say Y here to enable support for the IBM GXT4000P/6000P and
- GXT4500P/6500P display adaptor based on Raster Engine RC1000,
- found on some IBM System P (pSeries) machines. This driver
- doesn't use Geometry Engine GT1000.
-
-config FB_PS3
- tristate "PS3 GPU framebuffer driver"
- depends on FB && PS3_PS3AV
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
- ---help---
- Include support for the virtual frame buffer in the PS3 platform.
-
-config FB_PS3_DEFAULT_SIZE_M
- int "PS3 default frame buffer size (in MiB)"
- depends on FB_PS3
- default 9
- ---help---
- This is the default size (in MiB) of the virtual frame buffer in
- the PS3.
- The default value can be overridden on the kernel command line
- using the "ps3fb" option (e.g. "ps3fb=9M");
-
-config FB_XILINX
- tristate "Xilinx frame buffer support"
- depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Include support for the Xilinx ML300/ML403 reference design
- framebuffer. ML300 carries a 640*480 LCD display on the board,
- ML403 uses a standard DB15 VGA connector.
-
-config FB_GOLDFISH
- tristate "Goldfish Framebuffer"
- depends on FB && HAS_DMA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Framebuffer driver for Goldfish Virtual Platform
-
-config FB_COBALT
- tristate "Cobalt server LCD frame buffer support"
- depends on FB && (MIPS_COBALT || MIPS_SEAD3)
-
-config FB_SH7760
- bool "SH7760/SH7763/SH7720/SH7721 LCDC support"
- depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \
- || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Support for the SH7760/SH7763/SH7720/SH7721 integrated
- (D)STN/TFT LCD Controller.
- Supports display resolutions up to 1024x1024 pixel, grayscale and
- color operation, with depths ranging from 1 bpp to 8 bpp monochrome
- and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for
- panels <= 320 pixel horizontal resolution.
-
-config FB_DA8XX
- tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support"
- depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_CFB_REV_PIXELS_IN_BYTE
- select FB_MODE_HELPERS
- select VIDEOMODE_HELPERS
- ---help---
- This is the frame buffer device driver for the TI LCD controller
- found on DA8xx/OMAP-L1xx/AM335x SoCs.
- If unsure, say N.
-
-config FB_VIRTUAL
- tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
- depends on FB
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- ---help---
- This is a `virtual' frame buffer device. It operates on a chunk of
- unswappable kernel memory instead of on the memory of a graphics
- board. This means you cannot see any output sent to this frame
- buffer device, while it does consume precious memory. The main use
- of this frame buffer device is testing and debugging the frame
- buffer subsystem. Do NOT enable it for normal systems! To protect
- the innocent, it has to be enabled explicitly at boot time using the
- kernel option `video=vfb:'.
-
- To compile this driver as a module, choose M here: the
- module will be called vfb. In order to load it, you must use
- the vfb_enable=1 option.
-
- If unsure, say N.
-
-config XEN_FBDEV_FRONTEND
- tristate "Xen virtual frame buffer support"
- depends on FB && XEN
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC
- select XEN_XENBUS_FRONTEND
- default y
- help
- This driver implements the front-end of the Xen virtual
- frame buffer driver. It communicates with a back-end
- in another domain.
-
-config FB_METRONOME
- tristate "E-Ink Metronome/8track controller support"
- depends on FB
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- help
- This driver implements support for the E-Ink Metronome
- controller. The pre-release name for this device was 8track
- and could also have been called by some vendors as PVI-nnnn.
-
-config FB_MB862XX
- tristate "Fujitsu MB862xx GDC support"
- depends on FB
- depends on PCI || (OF && PPC)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers.
-
-choice
- prompt "GDC variant"
- depends on FB_MB862XX
-
-config FB_MB862XX_PCI_GDC
- bool "Carmine/Coral-P(A) GDC"
- depends on PCI
- ---help---
- This enables framebuffer support for Fujitsu Carmine/Coral-P(A)
- PCI graphics controller devices.
-
-config FB_MB862XX_LIME
- bool "Lime GDC"
- depends on OF && PPC
- select FB_FOREIGN_ENDIAN
- select FB_LITTLE_ENDIAN
- ---help---
- Framebuffer support for Fujitsu Lime GDC on host CPU bus.
-
-endchoice
-
-config FB_MB862XX_I2C
- bool "Support I2C bus on MB862XX GDC"
- depends on FB_MB862XX && I2C
- default y
- help
- Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter
- driver to support accessing I2C devices on controller's I2C bus.
- These are usually some video decoder chips.
-
-config FB_EP93XX
- tristate "EP93XX frame buffer support"
- depends on FB && ARCH_EP93XX
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Framebuffer driver for the Cirrus Logic EP93XX series of processors.
- This driver is also available as a module. The module will be called
- ep93xx-fb.
-
-config FB_PRE_INIT_FB
- bool "Don't reinitialize, use bootloader's GDC/Display configuration"
- depends on FB && FB_MB862XX_LIME
- ---help---
- Select this option if display contents should be inherited as set by
- the bootloader.
-
-config FB_MSM
- tristate "MSM Framebuffer support"
- depends on FB && ARCH_MSM
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
-
-config FB_MX3
- tristate "MX3 Framebuffer support"
- depends on FB && MX3_IPU
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- default y
- help
- This is a framebuffer device for the i.MX31 LCD Controller. So
- far only synchronous displays are supported. If you plan to use
- an LCD display with your i.MX31 system, say Y here.
-
-config FB_BROADSHEET
- tristate "E-Ink Broadsheet/Epson S1D13521 controller support"
- depends on FB
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- help
- This driver implements support for the E-Ink Broadsheet
- controller. The release name for this device was Epson S1D13521
- and could also have been called by other names when coupled with
- a bridge adapter.
-
-config FB_AUO_K190X
- tristate "AUO-K190X EPD controller support"
- depends on FB
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- help
- Provides support for epaper controllers from the K190X series
- of AUO. These controllers can be used to drive epaper displays
- from Sipix.
-
- This option enables the common support, shared by the individual
- controller drivers. You will also have to enable the driver
- for the controller type used in your device.
-
-config FB_AUO_K1900
- tristate "AUO-K1900 EPD controller support"
- depends on FB && FB_AUO_K190X
- help
- This driver implements support for the AUO K1900 epd-controller.
- This controller can drive Sipix epaper displays but can only do
- serial updates, reducing the number of possible frames per second.
-
-config FB_AUO_K1901
- tristate "AUO-K1901 EPD controller support"
- depends on FB && FB_AUO_K190X
- help
- This driver implements support for the AUO K1901 epd-controller.
- This controller can drive Sipix epaper displays and supports
- concurrent updates, making higher frames per second possible.
-
-config FB_JZ4740
- tristate "JZ4740 LCD framebuffer support"
- depends on FB && MACH_JZ4740
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- help
- Framebuffer support for the JZ4740 SoC.
-
-config FB_MXS
- tristate "MXS LCD framebuffer support"
- depends on FB && ARCH_MXS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MODE_HELPERS
- select VIDEOMODE_HELPERS
- help
- Framebuffer support for the MXS SoC.
-
-config FB_PUV3_UNIGFX
- tristate "PKUnity v3 Unigfx framebuffer support"
- depends on FB && UNICORE32 && ARCH_PUV3
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- help
- Choose this option if you want to use the Unigfx device as a
- framebuffer device. Without the support of PCI & AGP.
-
-config FB_HYPERV
- tristate "Microsoft Hyper-V Synthetic Video support"
- depends on FB && HYPERV
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
-
-config FB_SIMPLE
- bool "Simple framebuffer support"
- depends on (FB = y)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Say Y if you want support for a simple frame-buffer.
-
- This driver assumes that the display hardware has been initialized
- before the kernel boots, and the kernel will simply render to the
- pre-allocated frame buffer surface.
-
- Configuration re: surface address, size, and format must be provided
- through device tree, or plain old platform data.
-
-source "drivers/video/omap/Kconfig"
-source "drivers/video/omap2/Kconfig"
-source "drivers/video/exynos/Kconfig"
-source "drivers/video/mmp/Kconfig"
-source "drivers/video/backlight/Kconfig"
-
if VT
source "drivers/video/console/Kconfig"
endif
if FB || SGI_NEWPORT_CONSOLE
source "drivers/video/logo/Kconfig"
-endif
-config FB_SH_MOBILE_MERAM
- tristate "SuperH Mobile MERAM read ahead support"
- depends on (SUPERH || ARCH_SHMOBILE)
- select GENERIC_ALLOCATOR
- ---help---
- Enable MERAM support for the SuperH controller.
-
- This will allow for caching of the framebuffer to provide more
- reliable access under heavy main memory bus traffic situations.
- Up to 4 memory channels can be configured, allowing 4 RGB or
- 2 YCbCr framebuffers to be configured.
+endif
-config FB_SSD1307
- tristate "Solomon SSD1307 framebuffer support"
- depends on FB && I2C
- depends on OF
- depends on GPIOLIB
- select FB_SYS_FOPS
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_DEFERRED_IO
- select PWM
- help
- This driver implements support for the Solomon SSD1307
- OLED controller over I2C.
endmenu
-# Makefile for the Linux video drivers.
-# 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
-# Rewritten to use lists instead of if-statements.
-
-# Each configuration option enables a list of files.
-
obj-$(CONFIG_VGASTATE) += vgastate.o
obj-$(CONFIG_HDMI) += hdmi.o
-obj-y += fb_notify.o
-obj-$(CONFIG_FB) += fb.o
-fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
- modedb.o fbcvt.o
-fb-objs := $(fb-y)
obj-$(CONFIG_VT) += console/
obj-$(CONFIG_LOGO) += logo/
obj-y += backlight/
-obj-$(CONFIG_EXYNOS_VIDEO) += exynos/
-
-obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
-obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
-obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
-obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o
-obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o
-obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
-obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o
-obj-$(CONFIG_FB_SVGALIB) += svgalib.o
-obj-$(CONFIG_FB_MACMODES) += macmodes.o
-obj-$(CONFIG_FB_DDC) += fb_ddc.o
-obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
-obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o
-
-# Hardware specific drivers go first
-obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
-obj-$(CONFIG_FB_ARC) += arcfb.o
-obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
-obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
-obj-$(CONFIG_FB_GRVGA) += grvga.o
-obj-$(CONFIG_FB_PM2) += pm2fb.o
-obj-$(CONFIG_FB_PM3) += pm3fb.o
-
-obj-$(CONFIG_FB_I740) += i740fb.o
-obj-$(CONFIG_FB_MATROX) += matrox/
-obj-$(CONFIG_FB_RIVA) += riva/
-obj-$(CONFIG_FB_NVIDIA) += nvidia/
-obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
-obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
-obj-$(CONFIG_FB_RADEON) += aty/
-obj-$(CONFIG_FB_SIS) += sis/
-obj-$(CONFIG_FB_VIA) += via/
-obj-$(CONFIG_FB_KYRO) += kyro/
-obj-$(CONFIG_FB_SAVAGE) += savage/
-obj-$(CONFIG_FB_GEODE) += geode/
-obj-$(CONFIG_FB_MBX) += mbx/
-obj-$(CONFIG_FB_NEOMAGIC) += neofb.o
-obj-$(CONFIG_FB_3DFX) += tdfxfb.o
-obj-$(CONFIG_FB_CONTROL) += controlfb.o
-obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
-obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o
-obj-$(CONFIG_FB_CT65550) += chipsfb.o
-obj-$(CONFIG_FB_IMSTT) += imsttfb.o
-obj-$(CONFIG_FB_FM2) += fm2fb.o
-obj-$(CONFIG_FB_VT8623) += vt8623fb.o
-obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
-obj-$(CONFIG_FB_LE80578) += vermilion/
-obj-$(CONFIG_FB_S3) += s3fb.o
-obj-$(CONFIG_FB_ARK) += arkfb.o
-obj-$(CONFIG_FB_STI) += stifb.o
-obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o
-obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o
-obj-$(CONFIG_FB_CG3) += cg3.o sbuslib.o
-obj-$(CONFIG_FB_BW2) += bw2.o sbuslib.o
-obj-$(CONFIG_FB_CG14) += cg14.o sbuslib.o
-obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o
-obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o
-obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o
-obj-$(CONFIG_FB_ACORN) += acornfb.o
-obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \
- atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
-obj-$(CONFIG_FB_MAC) += macfb.o
-obj-$(CONFIG_FB_HECUBA) += hecubafb.o
-obj-$(CONFIG_FB_N411) += n411.o
-obj-$(CONFIG_FB_HGA) += hgafb.o
-obj-$(CONFIG_FB_XVR500) += sunxvr500.o
-obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o
-obj-$(CONFIG_FB_XVR1000) += sunxvr1000.o
-obj-$(CONFIG_FB_IGA) += igafb.o
-obj-$(CONFIG_FB_APOLLO) += dnfb.o
-obj-$(CONFIG_FB_Q40) += q40fb.o
-obj-$(CONFIG_FB_TGA) += tgafb.o
-obj-$(CONFIG_FB_HP300) += hpfb.o
-obj-$(CONFIG_FB_G364) += g364fb.o
-obj-$(CONFIG_FB_EP93XX) += ep93xx-fb.o
-obj-$(CONFIG_FB_SA1100) += sa1100fb.o
-obj-$(CONFIG_FB_HIT) += hitfb.o
-obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
-obj-$(CONFIG_FB_PVR2) += pvr2fb.o
-obj-$(CONFIG_FB_VOODOO1) += sstfb.o
-obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
-obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
-obj-$(CONFIG_FB_68328) += 68328fb.o
-obj-$(CONFIG_FB_GBE) += gbefb.o
-obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
-obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
-obj-$(CONFIG_FB_PXA) += pxafb.o
-obj-$(CONFIG_FB_PXA168) += pxa168fb.o
-obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o
-obj-$(CONFIG_MMP_DISP) += mmp/
-obj-$(CONFIG_FB_W100) += w100fb.o
-obj-$(CONFIG_FB_TMIO) += tmiofb.o
-obj-$(CONFIG_FB_AU1100) += au1100fb.o
-obj-$(CONFIG_FB_AU1200) += au1200fb.o
-obj-$(CONFIG_FB_VT8500) += vt8500lcdfb.o
-obj-$(CONFIG_FB_WM8505) += wm8505fb.o
-obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
-obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
-obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
-obj-$(CONFIG_FB_MAXINE) += maxinefb.o
-obj-$(CONFIG_FB_METRONOME) += metronomefb.o
-obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o
-obj-$(CONFIG_FB_AUO_K190X) += auo_k190x.o
-obj-$(CONFIG_FB_AUO_K1900) += auo_k1900fb.o
-obj-$(CONFIG_FB_AUO_K1901) += auo_k1901fb.o
-obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
-obj-$(CONFIG_FB_SH7760) += sh7760fb.o
-obj-$(CONFIG_FB_IMX) += imxfb.o
-obj-$(CONFIG_FB_S3C) += s3c-fb.o
-obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
-obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o
-obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o
-obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
-obj-$(CONFIG_FB_PS3) += ps3fb.o
-obj-$(CONFIG_FB_SM501) += sm501fb.o
-obj-$(CONFIG_FB_UDL) += udlfb.o
-obj-$(CONFIG_FB_SMSCUFX) += smscufx.o
-obj-$(CONFIG_FB_XILINX) += xilinxfb.o
-obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o
-obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o
-obj-$(CONFIG_FB_SH_MOBILE_MERAM) += sh_mobile_meram.o
-obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
-obj-$(CONFIG_FB_OMAP) += omap/
-obj-y += omap2/
-obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
-obj-$(CONFIG_FB_CARMINE) += carminefb.o
-obj-$(CONFIG_FB_MB862XX) += mb862xx/
-obj-$(CONFIG_FB_MSM) += msm/
-obj-$(CONFIG_FB_NUC900) += nuc900fb.o
-obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
-obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
-obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o
-obj-$(CONFIG_FB_OPENCORES) += ocfb.o
-
-# Platform or fallback drivers go here
-obj-$(CONFIG_FB_UVESA) += uvesafb.o
-obj-$(CONFIG_FB_VESA) += vesafb.o
-obj-$(CONFIG_FB_EFI) += efifb.o
-obj-$(CONFIG_FB_VGA16) += vga16fb.o
-obj-$(CONFIG_FB_OF) += offb.o
-obj-$(CONFIG_FB_BF537_LQ035) += bf537-lq035.o
-obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o
-obj-$(CONFIG_FB_BFIN_LQ035Q1) += bfin-lq035q1-fb.o
-obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o
-obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o
-obj-$(CONFIG_FB_MX3) += mx3fb.o
-obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o
-obj-$(CONFIG_FB_MXS) += mxsfb.o
-obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o
-obj-$(CONFIG_FB_SIMPLE) += simplefb.o
-
-# the test framebuffer is last
-obj-$(CONFIG_FB_VIRTUAL) += vfb.o
+obj-y += fbdev/
obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o
ifeq ($(CONFIG_OF),y)
#include <asm/io.h>
-#include "../sticore.h"
+#include "../fbdev/sticore.h"
/* switching to graphics mode */
#define BLANK 0
#include <asm/cacheflush.h>
#include <asm/grfioctl.h>
-#include "../sticore.h"
+#include "../fbdev/sticore.h"
#define STI_DRIVERVERSION "Version 0.9b"
--- /dev/null
+#
+# fbdev configuration
+#
+
+menuconfig FB
+ tristate "Support for frame buffer devices"
+ ---help---
+ The frame buffer device provides an abstraction for the graphics
+ hardware. It represents the frame buffer of some video hardware and
+ allows application software to access the graphics hardware through
+ a well-defined interface, so the software doesn't need to know
+ anything about the low-level (hardware register) stuff.
+
+ Frame buffer devices work identically across the different
+ architectures supported by Linux and make the implementation of
+ application programs easier and more portable; at this point, an X
+ server exists which uses the frame buffer device exclusively.
+ On several non-X86 architectures, the frame buffer device is the
+ only way to use the graphics hardware.
+
+ The device is accessed through special device nodes, usually located
+ in the /dev directory, i.e. /dev/fb*.
+
+ You need an utility program called fbset to make full use of frame
+ buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
+ and the Framebuffer-HOWTO at
+ <http://www.munted.org.uk/programming/Framebuffer-HOWTO-1.3.html> for more
+ information.
+
+ Say Y here and to the driver for your graphics board below if you
+ are compiling a kernel for a non-x86 architecture.
+
+ If you are compiling for the x86 architecture, you can say Y if you
+ want to play with it, but it is not essential. Please note that
+ running graphical applications that directly touch the hardware
+ (e.g. an accelerated X server) and that are not frame buffer
+ device-aware may cause unexpected results. If unsure, say N.
+
+config FIRMWARE_EDID
+ bool "Enable firmware EDID"
+ depends on FB
+ default n
+ ---help---
+ This enables access to the EDID transferred from the firmware.
+ On the i386, this is from the Video BIOS. Enable this if DDC/I2C
+ transfers do not work for your driver and if you are using
+ nvidiafb, i810fb or savagefb.
+
+ In general, choosing Y for this option is safe. If you
+ experience extremely long delays while booting before you get
+ something on your display, try setting this to N. Matrox cards in
+ combination with certain motherboards and monitors are known to
+ suffer from this problem.
+
+config FB_DDC
+ tristate
+ depends on FB
+ select I2C_ALGOBIT
+ select I2C
+ default n
+
+config FB_BOOT_VESA_SUPPORT
+ bool
+ depends on FB
+ default n
+ ---help---
+ If true, at least one selected framebuffer driver can take advantage
+ of VESA video modes set at an early boot stage via the vga= parameter.
+
+config FB_CFB_FILLRECT
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the cfb_fillrect function for generic software rectangle
+ filling. This is used by drivers that don't provide their own
+ (accelerated) version.
+
+config FB_CFB_COPYAREA
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the cfb_copyarea function for generic software area copying.
+ This is used by drivers that don't provide their own (accelerated)
+ version.
+
+config FB_CFB_IMAGEBLIT
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the cfb_imageblit function for generic software image
+ blitting. This is used by drivers that don't provide their own
+ (accelerated) version.
+
+config FB_CFB_REV_PIXELS_IN_BYTE
+ bool
+ depends on FB
+ default n
+ ---help---
+ Allow generic frame-buffer functions to work on displays with 1, 2
+ and 4 bits per pixel depths which has opposite order of pixels in
+ byte order to bytes in long order.
+
+config FB_SYS_FILLRECT
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the sys_fillrect function for generic software rectangle
+ filling. This is used by drivers that don't provide their own
+ (accelerated) version and the framebuffer is in system RAM.
+
+config FB_SYS_COPYAREA
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the sys_copyarea function for generic software area copying.
+ This is used by drivers that don't provide their own (accelerated)
+ version and the framebuffer is in system RAM.
+
+config FB_SYS_IMAGEBLIT
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the sys_imageblit function for generic software image
+ blitting. This is used by drivers that don't provide their own
+ (accelerated) version and the framebuffer is in system RAM.
+
+menuconfig FB_FOREIGN_ENDIAN
+ bool "Framebuffer foreign endianness support"
+ depends on FB
+ ---help---
+ This menu will let you enable support for the framebuffers with
+ non-native endianness (e.g. Little-Endian framebuffer on a
+ Big-Endian machine). Most probably you don't have such hardware,
+ so it's safe to say "n" here.
+
+choice
+ prompt "Choice endianness support"
+ depends on FB_FOREIGN_ENDIAN
+
+config FB_BOTH_ENDIAN
+ bool "Support for Big- and Little-Endian framebuffers"
+
+config FB_BIG_ENDIAN
+ bool "Support for Big-Endian framebuffers only"
+
+config FB_LITTLE_ENDIAN
+ bool "Support for Little-Endian framebuffers only"
+
+endchoice
+
+config FB_SYS_FOPS
+ tristate
+ depends on FB
+ default n
+
+config FB_DEFERRED_IO
+ bool
+ depends on FB
+
+config FB_HECUBA
+ tristate
+ depends on FB
+ depends on FB_DEFERRED_IO
+
+config FB_SVGALIB
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Common utility functions useful to fbdev drivers of VGA-based
+ cards.
+
+config FB_MACMODES
+ tristate
+ depends on FB
+ default n
+
+config FB_BACKLIGHT
+ bool
+ depends on FB
+ select BACKLIGHT_LCD_SUPPORT
+ select BACKLIGHT_CLASS_DEVICE
+ default n
+
+config FB_MODE_HELPERS
+ bool "Enable Video Mode Handling Helpers"
+ depends on FB
+ default n
+ ---help---
+ This enables functions for handling video modes using the
+ Generalized Timing Formula and the EDID parser. A few drivers rely
+ on this feature such as the radeonfb, rivafb, and the i810fb. If
+ your driver does not take advantage of this feature, choosing Y will
+ just increase the kernel size by about 5K.
+
+config FB_TILEBLITTING
+ bool "Enable Tile Blitting Support"
+ depends on FB
+ default n
+ ---help---
+ This enables tile blitting. Tile blitting is a drawing technique
+ where the screen is divided into rectangular sections (tiles), whereas
+ the standard blitting divides the screen into pixels. Because the
+ default drawing element is a tile, drawing functions will be passed
+ parameters in terms of number of tiles instead of number of pixels.
+ For example, to draw a single character, instead of using bitmaps,
+ an index to an array of bitmaps will be used. To clear or move a
+ rectangular section of a screen, the rectangle will be described in
+ terms of number of tiles in the x- and y-axis.
+
+ This is particularly important to one driver, matroxfb. If
+ unsure, say N.
+
+comment "Frame buffer hardware drivers"
+ depends on FB
+
+config FB_GRVGA
+ tristate "Aeroflex Gaisler framebuffer support"
+ depends on FB && SPARC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
+
+config FB_CIRRUS
+ tristate "Cirrus Logic support"
+ depends on FB && (ZORRO || PCI)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ This enables support for Cirrus Logic GD542x/543x based boards on
+ Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
+
+ If you have a PCI-based system, this enables support for these
+ chips: GD-543x, GD-544x, GD-5480.
+
+ Please read the file <file:Documentation/fb/cirrusfb.txt>.
+
+ Say N unless you have such a graphics board or plan to get one
+ before you next recompile the kernel.
+
+config FB_PM2
+ tristate "Permedia2 support"
+ depends on FB && ((AMIGA && BROKEN) || PCI)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for cards based on
+ the 3D Labs Permedia, Permedia 2 and Permedia 2V chips.
+ The driver was tested on the following cards:
+ Diamond FireGL 1000 PRO AGP
+ ELSA Gloria Synergy PCI
+ Appian Jeronimo PRO (both heads) PCI
+ 3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI
+ Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC
+ ASK Graphic Blaster Exxtreme AGP
+
+ To compile this driver as a module, choose M here: the
+ module will be called pm2fb.
+
+config FB_PM2_FIFO_DISCONNECT
+ bool "enable FIFO disconnect feature"
+ depends on FB_PM2 && PCI
+ help
+ Support the Permedia2 FIFO disconnect feature.
+
+config FB_ARMCLCD
+ tristate "ARM PrimeCell PL110 support"
+ depends on ARM || ARM64 || COMPILE_TEST
+ depends on FB && ARM_AMBA
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This framebuffer device driver is for the ARM PrimeCell PL110
+ Colour LCD controller. ARM PrimeCells provide the building
+ blocks for System on a Chip devices.
+
+ If you want to compile this as a module (=code which can be
+ inserted into and removed from the running kernel), say M
+ here and read <file:Documentation/kbuild/modules.txt>. The module
+ will be called amba-clcd.
+
+config FB_ACORN
+ bool "Acorn VIDC support"
+ depends on (FB = y) && ARM && ARCH_ACORN
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Acorn VIDC graphics
+ hardware found in Acorn RISC PCs and other ARM-based machines. If
+ unsure, say N.
+
+config FB_CLPS711X
+ bool "CLPS711X LCD support"
+ depends on (FB = y) && ARM && ARCH_CLPS711X
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Say Y to enable the Framebuffer driver for the CLPS7111 and
+ EP7212 processors.
+
+config FB_SA1100
+ bool "SA-1100 LCD support"
+ depends on (FB = y) && ARM && ARCH_SA1100
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is a framebuffer device for the SA-1100 LCD Controller.
+ See <http://www.linux-fbdev.org/> for information on framebuffer
+ devices.
+
+ If you plan to use the LCD display with your SA-1100 system, say
+ Y here.
+
+config FB_IMX
+ tristate "Freescale i.MX1/21/25/27 LCD support"
+ depends on FB && ARCH_MXC
+ select BACKLIGHT_LCD_SUPPORT
+ select LCD_CLASS_DEVICE
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MODE_HELPERS
+ select VIDEOMODE_HELPERS
+
+config FB_CYBER2000
+ tristate "CyberPro 2000/2010/5000 support"
+ depends on FB && PCI && (BROKEN || !SPARC64)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This enables support for the Integraphics CyberPro 20x0 and 5000
+ VGA chips used in the Rebel.com Netwinder and other machines.
+ Say Y if you have a NetWinder or a graphics card containing this
+ device, otherwise say N.
+
+config FB_CYBER2000_DDC
+ bool "DDC for CyberPro support"
+ depends on FB_CYBER2000
+ select FB_DDC
+ default y
+ help
+ Say Y here if you want DDC support for your CyberPro graphics
+ card. This is only I2C bus support, driver does not use EDID.
+
+config FB_CYBER2000_I2C
+ bool "CyberPro 2000/2010/5000 I2C support"
+ depends on FB_CYBER2000 && I2C && ARCH_NETWINDER
+ select I2C_ALGOBIT
+ help
+ Enable support for the I2C video decoder interface on the
+ Integraphics CyberPro 20x0 and 5000 VGA chips. This is used
+ on the Netwinder machines for the SAA7111 video capture.
+
+config FB_APOLLO
+ bool
+ depends on (FB = y) && APOLLO
+ default y
+ select FB_CFB_FILLRECT
+ select FB_CFB_IMAGEBLIT
+
+config FB_Q40
+ bool
+ depends on (FB = y) && Q40
+ default y
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+
+config FB_AMIGA
+ tristate "Amiga native chipset support"
+ depends on FB && AMIGA
+ help
+ This is the frame buffer device driver for the builtin graphics
+ chipset found in Amigas.
+
+ To compile this driver as a module, choose M here: the
+ module will be called amifb.
+
+config FB_AMIGA_OCS
+ bool "Amiga OCS chipset support"
+ depends on FB_AMIGA
+ help
+ This enables support for the original Agnus and Denise video chips,
+ found in the Amiga 1000 and most A500's and A2000's. If you intend
+ to run Linux on any of these systems, say Y; otherwise say N.
+
+config FB_AMIGA_ECS
+ bool "Amiga ECS chipset support"
+ depends on FB_AMIGA
+ help
+ This enables support for the Enhanced Chip Set, found in later
+ A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If
+ you intend to run Linux on any of these systems, say Y; otherwise
+ say N.
+
+config FB_AMIGA_AGA
+ bool "Amiga AGA chipset support"
+ depends on FB_AMIGA
+ help
+ This enables support for the Advanced Graphics Architecture (also
+ known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T
+ and CD32. If you intend to run Linux on any of these systems, say Y;
+ otherwise say N.
+
+config FB_FM2
+ bool "Amiga FrameMaster II/Rainbow II support"
+ depends on (FB = y) && ZORRO
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Amiga FrameMaster
+ card from BSC (exhibited 1992 but not shipped as a CBM product).
+
+config FB_ARC
+ tristate "Arc Monochrome LCD board support"
+ depends on FB && X86
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ help
+ This enables support for the Arc Monochrome LCD board. The board
+ is based on the KS-108 lcd controller and is typically a matrix
+ of 2*n chips. This driver was tested with a 128x64 panel. This
+ driver supports it for use with x86 SBCs through a 16 bit GPIO
+ interface (8 bit data, 8 bit control). If you anticipate using
+ this driver, say Y or M; otherwise say N. You must specify the
+ GPIO IO address to be used for setting control and data.
+
+config FB_ATARI
+ bool "Atari native chipset support"
+ depends on (FB = y) && ATARI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the builtin graphics
+ chipset found in Ataris.
+
+config FB_OF
+ bool "Open Firmware frame buffer device support"
+ depends on (FB = y) && (PPC64 || PPC_OF) && (!PPC_PSERIES || PCI)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES
+ help
+ Say Y if you want support with Open Firmware for your graphics
+ board.
+
+config FB_CONTROL
+ bool "Apple \"control\" display support"
+ depends on (FB = y) && PPC_PMAC && PPC32
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES
+ help
+ This driver supports a frame buffer for the graphics adapter in the
+ Power Macintosh 7300 and others.
+
+config FB_PLATINUM
+ bool "Apple \"platinum\" display support"
+ depends on (FB = y) && PPC_PMAC && PPC32
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES
+ help
+ This driver supports a frame buffer for the "platinum" graphics
+ adapter in some Power Macintoshes.
+
+config FB_VALKYRIE
+ bool "Apple \"valkyrie\" display support"
+ depends on (FB = y) && (MAC || (PPC_PMAC && PPC32))
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES
+ help
+ This driver supports a frame buffer for the "valkyrie" graphics
+ adapter in some Power Macintoshes.
+
+config FB_CT65550
+ bool "Chips 65550 display support"
+ depends on (FB = y) && PPC32 && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Chips & Technologies
+ 65550 graphics chip in PowerBooks.
+
+config FB_ASILIANT
+ bool "Asiliant (Chips) 69000 display support"
+ depends on (FB = y) && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Asiliant 69030 chipset
+
+config FB_IMSTT
+ bool "IMS Twin Turbo display support"
+ depends on (FB = y) && PCI
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES if PPC
+ help
+ The IMS Twin Turbo is a PCI-based frame buffer card bundled with
+ many Macintosh and compatible computers.
+
+config FB_VGA16
+ tristate "VGA 16-color graphics support"
+ depends on FB && (X86 || PPC)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ select FONT_8x16 if FRAMEBUFFER_CONSOLE
+ help
+ This is the frame buffer device driver for VGA 16 color graphic
+ cards. Say Y if you have such a card.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vga16fb.
+
+config FB_BF54X_LQ043
+ tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)"
+ depends on FB && (BF54x) && !BF542
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD
+
+config FB_BFIN_T350MCQB
+ tristate "Varitronix COG-T350MCQB TFT LCD display (BF527 EZKIT)"
+ depends on FB && BLACKFIN
+ select BFIN_GPTIMERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device driver for a Varitronix VL-PS-COG-T350MCQB-01 display TFT LCD
+ This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI
+ It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK.
+
+config FB_BFIN_LQ035Q1
+ tristate "SHARP LQ035Q1DH02 TFT LCD"
+ depends on FB && BLACKFIN && SPI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select BFIN_GPTIMERS
+ help
+ This is the framebuffer device driver for a SHARP LQ035Q1DH02 TFT display found on
+ the Blackfin Landscape LCD EZ-Extender Card.
+ This display is a QVGA 320x240 18-bit RGB display interfaced by an 16-bit wide PPI
+ It uses PPI[0..15] PPI_FS1, PPI_FS2 and PPI_CLK.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bfin-lq035q1-fb.
+
+config FB_BF537_LQ035
+ tristate "SHARP LQ035 TFT LCD (BF537 STAMP)"
+ depends on FB && (BF534 || BF536 || BF537) && I2C_BLACKFIN_TWI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select BFIN_GPTIMERS
+ help
+ This is the framebuffer device for a SHARP LQ035Q7DB03 TFT LCD
+ attached to a BF537.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bf537-lq035.
+
+config FB_BFIN_7393
+ tristate "Blackfin ADV7393 Video encoder"
+ depends on FB && BLACKFIN
+ select I2C
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for a ADV7393 video encoder
+ attached to a Blackfin on the PPI port.
+ If your Blackfin board has a ADV7393 select Y.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bfin_adv7393fb.
+
+choice
+ prompt "Video mode support"
+ depends on FB_BFIN_7393
+ default NTSC
+
+config NTSC
+ bool 'NTSC 720x480'
+
+config PAL
+ bool 'PAL 720x576'
+
+config NTSC_640x480
+ bool 'NTSC 640x480 (Experimental)'
+
+config PAL_640x480
+ bool 'PAL 640x480 (Experimental)'
+
+config NTSC_YCBCR
+ bool 'NTSC 720x480 YCbCR input'
+
+config PAL_YCBCR
+ bool 'PAL 720x576 YCbCR input'
+
+endchoice
+
+choice
+ prompt "Size of ADV7393 frame buffer memory Single/Double Size"
+ depends on (FB_BFIN_7393)
+ default ADV7393_1XMEM
+
+config ADV7393_1XMEM
+ bool 'Single'
+
+config ADV7393_2XMEM
+ bool 'Double'
+endchoice
+
+config FB_STI
+ tristate "HP STI frame buffer device support"
+ depends on FB && PARISC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select STI_CONSOLE
+ select VT
+ default y
+ ---help---
+ STI refers to the HP "Standard Text Interface" which is a set of
+ BIOS routines contained in a ROM chip in HP PA-RISC based machines.
+ Enabling this option will implement the linux framebuffer device
+ using calls to the STI BIOS routines for initialisation.
+
+ If you enable this option, you will get a planar framebuffer device
+ /dev/fb which will work on the most common HP graphic cards of the
+ NGLE family, including the artist chips (in the 7xx and Bxxx series),
+ HCRX, HCRX24, CRX, CRX24 and VisEG series.
+
+ It is safe to enable this option, so you should probably say "Y".
+
+config FB_MAC
+ bool "Generic Macintosh display support"
+ depends on (FB = y) && MAC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES
+
+config FB_HP300
+ bool
+ depends on (FB = y) && DIO
+ select FB_CFB_IMAGEBLIT
+ default y
+
+config FB_TGA
+ tristate "TGA/SFB+ framebuffer support"
+ depends on FB && (ALPHA || TC)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select BITREVERSE
+ ---help---
+ This is the frame buffer device driver for generic TGA and SFB+
+ graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards,
+ also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3
+ TURBOchannel cards, also known as PMAGD-A, -B and -C.
+
+ Due to hardware limitations ZLX-E2 and E3 cards are not supported
+ for DECstation 5000/200 systems. Additionally due to firmware
+ limitations these cards may cause troubles with booting DECstation
+ 5000/240 and /260 systems, but are fully supported under Linux if
+ you manage to get it going. ;-)
+
+ Say Y if you have one of those.
+
+config FB_UVESA
+ tristate "Userspace VESA VGA graphics support"
+ depends on FB && CONNECTOR
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MODE_HELPERS
+ help
+ This is the frame buffer driver for generic VBE 2.0 compliant
+ graphic cards. It can also take advantage of VBE 3.0 features,
+ such as refresh rate adjustment.
+
+ This driver generally provides more features than vesafb but
+ requires a userspace helper application called 'v86d'. See
+ <file:Documentation/fb/uvesafb.txt> for more information.
+
+ If unsure, say N.
+
+config FB_VESA
+ bool "VESA VGA graphics support"
+ depends on (FB = y) && X86
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_BOOT_VESA_SUPPORT
+ help
+ This is the frame buffer device driver for generic VESA 2.0
+ compliant graphic cards. The older VESA 1.2 cards are not supported.
+ You will get a boot time penguin logo at no additional cost. Please
+ read <file:Documentation/fb/vesafb.txt>. If unsure, say Y.
+
+config FB_EFI
+ bool "EFI-based Framebuffer Support"
+ depends on (FB = y) && X86 && EFI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the EFI frame buffer device driver. If the firmware on
+ your platform is EFI 1.10 or UEFI 2.0, select Y to add support for
+ using the EFI framebuffer as your console.
+
+config FB_N411
+ tristate "N411 Apollo/Hecuba devkit support"
+ depends on FB && X86 && MMU
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ select FB_HECUBA
+ help
+ This enables support for the Apollo display controller in its
+ Hecuba form using the n411 devkit.
+
+config FB_HGA
+ tristate "Hercules mono graphics support"
+ depends on FB && X86
+ help
+ Say Y here if you have a Hercules mono graphics card.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hgafb.
+
+ As this card technology is at least 25 years old,
+ most people will answer N here.
+
+config FB_GBE
+ bool "SGI Graphics Backend frame buffer support"
+ depends on (FB = y) && SGI_IP32
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for SGI Graphics Backend.
+ This chip is used in SGI O2 and Visual Workstation 320/540.
+
+config FB_GBE_MEM
+ int "Video memory size in MB"
+ depends on FB_GBE
+ default 4
+ help
+ This is the amount of memory reserved for the framebuffer,
+ which can be any value between 1MB and 8MB.
+
+config FB_SBUS
+ bool "SBUS and UPA framebuffers"
+ depends on (FB = y) && SPARC
+ help
+ Say Y if you want support for SBUS or UPA based frame buffer device.
+
+config FB_BW2
+ bool "BWtwo support"
+ depends on (FB = y) && (SPARC && FB_SBUS)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the BWtwo frame buffer.
+
+config FB_CG3
+ bool "CGthree support"
+ depends on (FB = y) && (SPARC && FB_SBUS)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the CGthree frame buffer.
+
+config FB_CG6
+ bool "CGsix (GX,TurboGX) support"
+ depends on (FB = y) && (SPARC && FB_SBUS)
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the CGsix (GX, TurboGX)
+ frame buffer.
+
+config FB_FFB
+ bool "Creator/Creator3D/Elite3D support"
+ depends on FB_SBUS && SPARC64
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Creator, Creator3D,
+ and Elite3D graphics boards.
+
+config FB_TCX
+ bool "TCX (SS4/SS5 only) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the TCX 24/8bit frame
+ buffer.
+
+config FB_CG14
+ bool "CGfourteen (SX) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the CGfourteen frame
+ buffer on Desktop SPARCsystems with the SX graphics option.
+
+config FB_P9100
+ bool "P9100 (Sparcbook 3 only) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the P9100 card
+ supported on Sparcbook 3 machines.
+
+config FB_LEO
+ bool "Leo (ZX) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the SBUS-based Sun ZX
+ (leo) frame buffer cards.
+
+config FB_IGA
+ bool "IGA 168x display support"
+ depends on (FB = y) && SPARC32
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the INTERGRAPHICS 1680 and
+ successor frame buffer cards.
+
+config FB_XVR500
+ bool "Sun XVR-500 3DLABS Wildcat support"
+ depends on (FB = y) && PCI && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-500 and similar
+ graphics cards based upon the 3DLABS Wildcat chipset. The driver
+ only works on sparc64 systems where the system firmware has
+ mostly initialized the card already. It is treated as a
+ completely dumb framebuffer device.
+
+config FB_XVR2500
+ bool "Sun XVR-2500 3DLABS Wildcat support"
+ depends on (FB = y) && PCI && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-2500 and similar
+ graphics cards based upon the 3DLABS Wildcat chipset. The driver
+ only works on sparc64 systems where the system firmware has
+ mostly initialized the card already. It is treated as a
+ completely dumb framebuffer device.
+
+config FB_XVR1000
+ bool "Sun XVR-1000 support"
+ depends on (FB = y) && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-1000 and similar
+ graphics cards. The driver only works on sparc64 systems where
+ the system firmware has mostly initialized the card already. It
+ is treated as a completely dumb framebuffer device.
+
+config FB_PVR2
+ tristate "NEC PowerVR 2 display support"
+ depends on FB && SH_DREAMCAST
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Say Y here if you have a PowerVR 2 card in your box. If you plan to
+ run linux on your Dreamcast, you will have to say Y here.
+ This driver may or may not work on other PowerVR 2 cards, but is
+ totally untested. Use at your own risk. If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called pvr2fb.
+
+ You can pass several parameters to the driver at boot time or at
+ module load time. The parameters look like "video=pvr2:XXX", where
+ the meaning of XXX can be found at the end of the main source file
+ (<file:drivers/video/pvr2fb.c>). Please see the file
+ <file:Documentation/fb/pvr2fb.txt>.
+
+config FB_OPENCORES
+ tristate "OpenCores VGA/LCD core 2.0 framebuffer support"
+ depends on FB && HAS_DMA
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This enables support for the OpenCores VGA/LCD core.
+
+ The OpenCores VGA/LCD core is typically used together with
+ softcore CPUs (e.g. OpenRISC or Microblaze) or hard processor
+ systems (e.g. Altera socfpga or Xilinx Zynq) on FPGAs.
+
+ The source code and specification for the core is available at
+ <http://opencores.org/project,vga_lcd>
+
+config FB_S1D13XXX
+ tristate "Epson S1D13XXX framebuffer support"
+ depends on FB
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Support for S1D13XXX framebuffer device family (currently only
+ working with S1D13806). Product specs at
+ <http://vdc.epson.com/>
+
+config FB_ATMEL
+ tristate "AT91/AT32 LCD Controller support"
+ depends on FB && HAVE_FB_ATMEL
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MODE_HELPERS
+ select VIDEOMODE_HELPERS
+ help
+ This enables support for the AT91/AT32 LCD Controller.
+
+config FB_INTSRAM
+ bool "Frame Buffer in internal SRAM"
+ depends on FB_ATMEL && ARCH_AT91SAM9261
+ help
+ Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want
+ to let frame buffer in external SDRAM.
+
+config FB_ATMEL_STN
+ bool "Use a STN display with AT91/AT32 LCD Controller"
+ depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK)
+ default n
+ help
+ Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD
+ Controller. Say N if you want to connect a TFT.
+
+ If unsure, say N.
+
+config FB_NVIDIA
+ tristate "nVidia Framebuffer Support"
+ depends on FB && PCI
+ select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select BITREVERSE
+ select VGASTATE
+ help
+ This driver supports graphics boards with the nVidia chips, TNT
+ and newer. For very old chipsets, such as the RIVA128, then use
+ the rivafb.
+ Say Y if you have such a graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called nvidiafb.
+
+config FB_NVIDIA_I2C
+ bool "Enable DDC Support"
+ depends on FB_NVIDIA
+ select FB_DDC
+ help
+ This enables I2C support for nVidia Chipsets. This is used
+ only for getting EDID information from the attached display
+ allowing for robust video mode handling and switching.
+
+ Because fbdev-2.6 requires that drivers must be able to
+ independently validate video mode parameters, you should say Y
+ here.
+
+config FB_NVIDIA_DEBUG
+ bool "Lots of debug output"
+ depends on FB_NVIDIA
+ default n
+ help
+ Say Y here if you want the nVidia driver to output all sorts
+ of debugging information to provide to the maintainer when
+ something goes wrong.
+
+config FB_NVIDIA_BACKLIGHT
+ bool "Support for backlight control"
+ depends on FB_NVIDIA
+ default y
+ help
+ Say Y here if you want to control the backlight of your display.
+
+config FB_RIVA
+ tristate "nVidia Riva support"
+ depends on FB && PCI
+ select FB_BACKLIGHT if FB_RIVA_BACKLIGHT
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select BITREVERSE
+ select VGASTATE
+ help
+ This driver supports graphics boards with the nVidia Riva/Geforce
+ chips.
+ Say Y if you have such a graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rivafb.
+
+config FB_RIVA_I2C
+ bool "Enable DDC Support"
+ depends on FB_RIVA
+ select FB_DDC
+ help
+ This enables I2C support for nVidia Chipsets. This is used
+ only for getting EDID information from the attached display
+ allowing for robust video mode handling and switching.
+
+ Because fbdev-2.6 requires that drivers must be able to
+ independently validate video mode parameters, you should say Y
+ here.
+
+config FB_RIVA_DEBUG
+ bool "Lots of debug output"
+ depends on FB_RIVA
+ default n
+ help
+ Say Y here if you want the Riva driver to output all sorts
+ of debugging information to provide to the maintainer when
+ something goes wrong.
+
+config FB_RIVA_BACKLIGHT
+ bool "Support for backlight control"
+ depends on FB_RIVA
+ default y
+ help
+ Say Y here if you want to control the backlight of your display.
+
+config FB_I740
+ tristate "Intel740 support"
+ depends on FB && PCI
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ select FB_DDC
+ help
+ This driver supports graphics cards based on Intel740 chip.
+
+config FB_I810
+ tristate "Intel 810/815 support"
+ depends on FB && PCI && X86_32 && AGP_INTEL
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ help
+ This driver supports the on-board graphics built in to the Intel 810
+ and 815 chipsets. Say Y if you have and plan to use such a board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called i810fb.
+
+ For more information, please read
+ <file:Documentation/fb/intel810.txt>
+
+config FB_I810_GTF
+ bool "use VESA Generalized Timing Formula"
+ depends on FB_I810
+ help
+ If you say Y, then the VESA standard, Generalized Timing Formula
+ or GTF, will be used to calculate the required video timing values
+ per video mode. Since the GTF allows nondiscrete timings
+ (nondiscrete being a range of values as opposed to discrete being a
+ set of values), you'll be able to use any combination of horizontal
+ and vertical resolutions, and vertical refresh rates without having
+ to specify your own timing parameters. This is especially useful
+ to maximize the performance of an aging display, or if you just
+ have a display with nonstandard dimensions. A VESA compliant
+ monitor is recommended, but can still work with non-compliant ones.
+ If you need or want this, then select this option. The timings may
+ not be compliant with Intel's recommended values. Use at your own
+ risk.
+
+ If you say N, the driver will revert to discrete video timings
+ using a set recommended by Intel in their documentation.
+
+ If unsure, say N.
+
+config FB_I810_I2C
+ bool "Enable DDC Support"
+ depends on FB_I810 && FB_I810_GTF
+ select FB_DDC
+ help
+
+config FB_LE80578
+ tristate "Intel LE80578 (Vermilion) support"
+ depends on FB && PCI && X86
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This driver supports the LE80578 (Vermilion Range) chipset
+
+config FB_CARILLO_RANCH
+ tristate "Intel Carillo Ranch support"
+ depends on FB_LE80578 && FB && PCI && X86
+ help
+ This driver supports the LE80578 (Carillo Ranch) board
+
+config FB_INTEL
+ tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support"
+ depends on FB && PCI && X86 && AGP_INTEL && EXPERT
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_BOOT_VESA_SUPPORT if FB_INTEL = y
+ depends on !DRM_I915
+ help
+ This driver supports the on-board graphics built in to the Intel
+ 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
+ Say Y if you have and plan to use such a board.
+
+ To make FB_INTELFB=Y work you need to say AGP_INTEL=y too.
+
+ To compile this driver as a module, choose M here: the
+ module will be called intelfb.
+
+ For more information, please read <file:Documentation/fb/intelfb.txt>
+
+config FB_INTEL_DEBUG
+ bool "Intel driver Debug Messages"
+ depends on FB_INTEL
+ ---help---
+ Say Y here if you want the Intel driver to output all sorts
+ of debugging information to provide to the maintainer when
+ something goes wrong.
+
+config FB_INTEL_I2C
+ bool "DDC/I2C for Intel framebuffer support"
+ depends on FB_INTEL
+ select FB_DDC
+ default y
+ help
+ Say Y here if you want DDC/I2C support for your on-board Intel graphics.
+
+config FB_MATROX
+ tristate "Matrox acceleration"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_TILEBLITTING
+ select FB_MACMODES if PPC_PMAC
+ ---help---
+ Say Y here if you have a Matrox Millennium, Matrox Millennium II,
+ Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
+ Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video,
+ Matrox G400, G450 or G550 card in your box.
+
+ To compile this driver as a module, choose M here: the
+ module will be called matroxfb.
+
+ You can pass several parameters to the driver at boot time or at
+ module load time. The parameters look like "video=matroxfb:XXX", and
+ are described in <file:Documentation/fb/matroxfb.txt>.
+
+config FB_MATROX_MILLENIUM
+ bool "Millennium I/II support"
+ depends on FB_MATROX
+ help
+ Say Y here if you have a Matrox Millennium or Matrox Millennium II
+ video card. If you select "Advanced lowlevel driver options" below,
+ you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp
+ packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can
+ also use font widths different from 8.
+
+config FB_MATROX_MYSTIQUE
+ bool "Mystique support"
+ depends on FB_MATROX
+ help
+ Say Y here if you have a Matrox Mystique or Matrox Mystique 220
+ video card. If you select "Advanced lowlevel driver options" below,
+ you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp
+ packed pixel and 32 bpp packed pixel. You can also use font widths
+ different from 8.
+
+config FB_MATROX_G
+ bool "G100/G200/G400/G450/G550 support"
+ depends on FB_MATROX
+ ---help---
+ Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based
+ video card. If you select "Advanced lowlevel driver options", you
+ should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
+ pixel and 32 bpp packed pixel. You can also use font widths
+ different from 8.
+
+ If you need support for G400 secondary head, you must say Y to
+ "Matrox I2C support" and "G400 second head support" right below.
+ G450/G550 secondary head and digital output are supported without
+ additional modules.
+
+ The driver starts in monitor mode. You must use the matroxset tool
+ (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to
+ swap primary and secondary head outputs, or to change output mode.
+ Secondary head driver always start in 640x480 resolution and you
+ must use fbset to change it.
+
+ Do not forget that second head supports only 16 and 32 bpp
+ packed pixels, so it is a good idea to compile them into the kernel
+ too. You can use only some font widths, as the driver uses generic
+ painting procedures (the secondary head does not use acceleration
+ engine).
+
+ G450/G550 hardware can display TV picture only from secondary CRTC,
+ and it performs no scaling, so picture must have 525 or 625 lines.
+
+config FB_MATROX_I2C
+ tristate "Matrox I2C support"
+ depends on FB_MATROX
+ select FB_DDC
+ ---help---
+ This drivers creates I2C buses which are needed for accessing the
+ DDC (I2C) bus present on all Matroxes, an I2C bus which
+ interconnects Matrox optional devices, like MGA-TVO on G200 and
+ G400, and the secondary head DDC bus, present on G400 only.
+
+ You can say Y or M here if you want to experiment with monitor
+ detection code. You must say Y or M here if you want to use either
+ second head of G400 or MGA-TVO on G200 or G400.
+
+ If you compile it as module, it will create a module named
+ i2c-matroxfb.
+
+config FB_MATROX_MAVEN
+ tristate "G400 second head support"
+ depends on FB_MATROX_G && FB_MATROX_I2C
+ ---help---
+ WARNING !!! This support does not work with G450 !!!
+
+ Say Y or M here if you want to use a secondary head (meaning two
+ monitors in parallel) on G400 or MGA-TVO add-on on G200. Secondary
+ head is not compatible with accelerated XFree 3.3.x SVGA servers -
+ secondary head output is blanked while you are in X. With XFree
+ 3.9.17 preview you can use both heads if you use SVGA over fbdev or
+ the fbdev driver on first head and the fbdev driver on second head.
+
+ If you compile it as module, two modules are created,
+ matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for
+ both G200 and G400, matroxfb_crtc2 is needed only by G400. You must
+ also load i2c-matroxfb to get it to run.
+
+ The driver starts in monitor mode and you must use the matroxset
+ tool (available at
+ <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to switch it to
+ PAL or NTSC or to swap primary and secondary head outputs.
+ Secondary head driver also always start in 640x480 resolution, you
+ must use fbset to change it.
+
+ Also do not forget that second head supports only 16 and 32 bpp
+ packed pixels, so it is a good idea to compile them into the kernel
+ too. You can use only some font widths, as the driver uses generic
+ painting procedures (the secondary head does not use acceleration
+ engine).
+
+config FB_RADEON
+ tristate "ATI Radeon display support"
+ depends on FB && PCI
+ select FB_BACKLIGHT if FB_RADEON_BACKLIGHT
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES if PPC_OF
+ help
+ Choose this option if you want to use an ATI Radeon graphics card as
+ a framebuffer device. There are both PCI and AGP versions. You
+ don't need to choose this to run the Radeon in plain VGA mode.
+
+ There is a product page at
+ http://products.amd.com/en-us/GraphicCardResult.aspx
+
+config FB_RADEON_I2C
+ bool "DDC/I2C for ATI Radeon support"
+ depends on FB_RADEON
+ select FB_DDC
+ default y
+ help
+ Say Y here if you want DDC/I2C support for your Radeon board.
+
+config FB_RADEON_BACKLIGHT
+ bool "Support for backlight control"
+ depends on FB_RADEON
+ default y
+ help
+ Say Y here if you want to control the backlight of your display.
+
+config FB_RADEON_DEBUG
+ bool "Lots of debug output from Radeon driver"
+ depends on FB_RADEON
+ default n
+ help
+ Say Y here if you want the Radeon driver to output all sorts
+ of debugging information to provide to the maintainer when
+ something goes wrong.
+
+config FB_ATY128
+ tristate "ATI Rage128 display support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_BACKLIGHT if FB_ATY128_BACKLIGHT
+ select FB_MACMODES if PPC_PMAC
+ help
+ This driver supports graphics boards with the ATI Rage128 chips.
+ Say Y if you have such a graphics board and read
+ <file:Documentation/fb/aty128fb.txt>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called aty128fb.
+
+config FB_ATY128_BACKLIGHT
+ bool "Support for backlight control"
+ depends on FB_ATY128
+ default y
+ help
+ Say Y here if you want to control the backlight of your display.
+
+config FB_ATY
+ tristate "ATI Mach64 display support" if PCI || ATARI
+ depends on FB && !SPARC32
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_BACKLIGHT if FB_ATY_BACKLIGHT
+ select FB_MACMODES if PPC
+ help
+ This driver supports graphics boards with the ATI Mach64 chips.
+ Say Y if you have such a graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called atyfb.
+
+config FB_ATY_CT
+ bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
+ depends on PCI && FB_ATY
+ default y if SPARC64 && PCI
+ help
+ Say Y here to support use of ATI's 64-bit Rage boards (or other
+ boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
+ framebuffer device. The ATI product support page for these boards
+ is at <http://support.ati.com/products/pc/mach64/mach64.html>.
+
+config FB_ATY_GENERIC_LCD
+ bool "Mach64 generic LCD support"
+ depends on FB_ATY_CT
+ help
+ Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility,
+ Rage XC, or Rage XL chipset.
+
+config FB_ATY_GX
+ bool "Mach64 GX support" if PCI
+ depends on FB_ATY
+ default y if ATARI
+ help
+ Say Y here to support use of the ATI Mach64 Graphics Expression
+ board (or other boards based on the Mach64 GX chipset) as a
+ framebuffer device. The ATI product support page for these boards
+ is at
+ <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
+
+config FB_ATY_BACKLIGHT
+ bool "Support for backlight control"
+ depends on FB_ATY
+ default y
+ help
+ Say Y here if you want to control the backlight of your display.
+
+config FB_S3
+ tristate "S3 Trio/Virge support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_TILEBLITTING
+ select FB_SVGALIB
+ select VGASTATE
+ select FONT_8x16 if FRAMEBUFFER_CONSOLE
+ ---help---
+ Driver for graphics boards with S3 Trio / S3 Virge chip.
+
+config FB_S3_DDC
+ bool "DDC for S3 support"
+ depends on FB_S3
+ select FB_DDC
+ default y
+ help
+ Say Y here if you want DDC support for your S3 graphics card.
+
+config FB_SAVAGE
+ tristate "S3 Savage support"
+ depends on FB && PCI
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ help
+ This driver supports notebooks and computers with S3 Savage PCI/AGP
+ chips.
+
+ Say Y if you have such a graphics card.
+
+ To compile this driver as a module, choose M here; the module
+ will be called savagefb.
+
+config FB_SAVAGE_I2C
+ bool "Enable DDC2 Support"
+ depends on FB_SAVAGE
+ select FB_DDC
+ help
+ This enables I2C support for S3 Savage Chipsets. This is used
+ only for getting EDID information from the attached display
+ allowing for robust video mode handling and switching.
+
+ Because fbdev-2.6 requires that drivers must be able to
+ independently validate video mode parameters, you should say Y
+ here.
+
+config FB_SAVAGE_ACCEL
+ bool "Enable Console Acceleration"
+ depends on FB_SAVAGE
+ default n
+ help
+ This option will compile in console acceleration support. If
+ the resulting framebuffer console has bothersome glitches, then
+ choose N here.
+
+config FB_SIS
+ tristate "SiS/XGI display support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_BOOT_VESA_SUPPORT if FB_SIS = y
+ help
+ This is the frame buffer device driver for the SiS 300, 315, 330
+ and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
+ Specs available at <http://www.sis.com> and <http://www.xgitech.com>.
+
+ To compile this driver as a module, choose M here; the module
+ will be called sisfb.
+
+config FB_SIS_300
+ bool "SiS 300 series support"
+ depends on FB_SIS
+ help
+ Say Y here to support use of the SiS 300/305, 540, 630 and 730.
+
+config FB_SIS_315
+ bool "SiS 315/330/340 series and XGI support"
+ depends on FB_SIS
+ help
+ Say Y here to support use of the SiS 315, 330 and 340 series
+ (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
+ as XGI V3XT, V5, V8 and Z7.
+
+config FB_VIA
+ tristate "VIA UniChrome (Pro) and Chrome9 display support"
+ depends on FB && PCI && X86
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select I2C_ALGOBIT
+ select I2C
+ select GPIOLIB
+ help
+ This is the frame buffer device driver for Graphics chips of VIA
+ UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
+ CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896
+ /P4M900,VX800)
+ Say Y if you have a VIA UniChrome graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called viafb.
+
+if FB_VIA
+
+config FB_VIA_DIRECT_PROCFS
+ bool "direct hardware access via procfs (DEPRECATED)(DANGEROUS)"
+ depends on FB_VIA
+ default n
+ help
+ Allow direct hardware access to some output registers via procfs.
+ This is dangerous but may provide the only chance to get the
+ correct output device configuration.
+ Its use is strongly discouraged.
+
+config FB_VIA_X_COMPATIBILITY
+ bool "X server compatibility"
+ depends on FB_VIA
+ default n
+ help
+ This option reduces the functionality (power saving, ...) of the
+ framebuffer to avoid negative impact on the OpenChrome X server.
+ If you use any X server other than fbdev you should enable this
+ otherwise it should be safe to disable it and allow using all
+ features.
+
+endif
+
+config FB_NEOMAGIC
+ tristate "NeoMagic display support"
+ depends on FB && PCI
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ help
+ This driver supports notebooks with NeoMagic PCI chips.
+ Say Y if you have such a graphics card.
+
+ To compile this driver as a module, choose M here: the
+ module will be called neofb.
+
+config FB_KYRO
+ tristate "IMG Kyro support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Say Y here if you have a STG4000 / Kyro / PowerVR 3 based
+ graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called kyrofb.
+
+config FB_3DFX
+ tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support"
+ depends on FB && PCI
+ select FB_CFB_IMAGEBLIT
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_MODE_HELPERS
+ help
+ This driver supports graphics boards with the 3Dfx Banshee,
+ Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have
+ such a graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tdfxfb.
+
+config FB_3DFX_ACCEL
+ bool "3Dfx Acceleration functions"
+ depends on FB_3DFX
+ ---help---
+ This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
+ device driver with acceleration functions.
+
+config FB_3DFX_I2C
+ bool "Enable DDC/I2C support"
+ depends on FB_3DFX
+ select FB_DDC
+ default y
+ help
+ Say Y here if you want DDC/I2C support for your 3dfx Voodoo3.
+
+config FB_VOODOO1
+ tristate "3Dfx Voodoo Graphics (sst1) support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
+ Voodoo2 (cvg) based graphics card.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sstfb.
+
+ WARNING: Do not use any application that uses the 3D engine
+ (namely glide) while using this driver.
+ Please read the <file:Documentation/fb/sstfb.txt> for supported
+ options and other important info support.
+
+config FB_VT8623
+ tristate "VIA VT8623 support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_TILEBLITTING
+ select FB_SVGALIB
+ select VGASTATE
+ select FONT_8x16 if FRAMEBUFFER_CONSOLE
+ ---help---
+ Driver for CastleRock integrated graphics core in the
+ VIA VT8623 [Apollo CLE266] chipset.
+
+config FB_TRIDENT
+ tristate "Trident/CyberXXX/CyberBlade support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ This is the frame buffer device driver for Trident PCI/AGP chipsets.
+ Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D
+ and Blade XP.
+ There are also integrated versions of these chips called CyberXXXX,
+ CyberImage or CyberBlade. These chips are mostly found in laptops
+ but also on some motherboards including early VIA EPIA motherboards.
+ For more information, read <file:Documentation/fb/tridentfb.txt>
+
+ Say Y if you have such a graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tridentfb.
+
+config FB_ARK
+ tristate "ARK 2000PV support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_TILEBLITTING
+ select FB_SVGALIB
+ select VGASTATE
+ select FONT_8x16 if FRAMEBUFFER_CONSOLE
+ ---help---
+ Driver for PCI graphics boards with ARK 2000PV chip
+ and ICS 5342 RAMDAC.
+
+config FB_PM3
+ tristate "Permedia3 support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the 3DLabs Permedia3
+ chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
+ similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
+ and maybe other boards.
+
+config FB_CARMINE
+ tristate "Fujitsu carmine frame buffer support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Fujitsu Carmine chip.
+ The driver provides two independent frame buffer devices.
+
+choice
+ depends on FB_CARMINE
+ prompt "DRAM timing"
+ default FB_CARMINE_DRAM_EVAL
+
+config FB_CARMINE_DRAM_EVAL
+ bool "Eval board timings"
+ help
+ Use timings which work on the eval card.
+
+config CARMINE_DRAM_CUSTOM
+ bool "Custom board timings"
+ help
+ Use custom board timings.
+endchoice
+
+config FB_AU1100
+ bool "Au1100 LCD Driver"
+ depends on (FB = y) && MIPS_ALCHEMY
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer driver for the AMD Au1100 SOC. It can drive
+ various panels and CRTs by passing in kernel cmd line option
+ au1100fb:panel=<name>.
+
+config FB_AU1200
+ bool "Au1200/Au1300 LCD Driver"
+ depends on (FB = y) && MIPS_ALCHEMY
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ help
+ This is the framebuffer driver for the Au1200/Au1300 SOCs.
+ It can drive various panels and CRTs by passing in kernel cmd line
+ option au1200fb:panel=<name>.
+
+config FB_VT8500
+ bool "VIA VT8500 framebuffer support"
+ depends on (FB = y) && ARM && ARCH_VT8500
+ select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
+ select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
+ select FB_SYS_IMAGEBLIT
+ select FB_MODE_HELPERS
+ select VIDEOMODE_HELPERS
+ help
+ This is the framebuffer driver for VIA VT8500 integrated LCD
+ controller.
+
+config FB_WM8505
+ bool "Wondermedia WM8xxx-series frame buffer support"
+ depends on (FB = y) && ARM && ARCH_VT8500
+ select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
+ select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
+ select FB_SYS_IMAGEBLIT
+ select FB_MODE_HELPERS
+ select VIDEOMODE_HELPERS
+ help
+ This is the framebuffer driver for WonderMedia WM8xxx-series
+ integrated LCD controller. This driver covers the WM8505, WM8650
+ and WM8850 SoCs.
+
+config FB_WMT_GE_ROPS
+ bool "VT8500/WM8xxx accelerated raster ops support"
+ depends on (FB = y) && (FB_VT8500 || FB_WM8505)
+ default n
+ help
+ This adds support for accelerated raster operations on the
+ VIA VT8500 and Wondermedia 85xx series SoCs.
+
+source "drivers/video/fbdev/geode/Kconfig"
+
+config FB_HIT
+ tristate "HD64461 Frame Buffer support"
+ depends on FB && HD64461
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Hitachi HD64461 LCD
+ frame buffer card.
+
+config FB_PMAG_AA
+ bool "PMAG-AA TURBOchannel framebuffer support"
+ depends on (FB = y) && TC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
+ used mainly in the MIPS-based DECstation series.
+
+config FB_PMAG_BA
+ tristate "PMAG-BA TURBOchannel framebuffer support"
+ depends on FB && TC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
+ used mainly in the MIPS-based DECstation series.
+
+config FB_PMAGB_B
+ tristate "PMAGB-B TURBOchannel framebuffer support"
+ depends on FB && TC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Support for the PMAGB-B TURBOchannel framebuffer card used mainly
+ in the MIPS-based DECstation series. The card is currently only
+ supported in 1280x1024x8 mode.
+
+config FB_MAXINE
+ bool "Maxine (Personal DECstation) onboard framebuffer support"
+ depends on (FB = y) && MACH_DECSTATION
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Support for the onboard framebuffer (1024x768x8) in the Personal
+ DECstation series (Personal DECstation 5000/20, /25, /33, /50,
+ Codename "Maxine").
+
+config FB_G364
+ bool "G364 frame buffer support"
+ depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ The G364 driver is the framebuffer used in MIPS Magnum 4000 and
+ Olivetti M700-10 systems.
+
+config FB_68328
+ bool "Motorola 68328 native frame buffer support"
+ depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Say Y here if you want to support the built-in frame buffer of
+ the Motorola 68328 CPU family.
+
+config FB_PXA168
+ tristate "PXA168/910 LCD framebuffer support"
+ depends on FB && (CPU_PXA168 || CPU_PXA910)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the built-in LCD controller in the Marvell
+ MMP processor.
+
+config FB_PXA
+ tristate "PXA LCD framebuffer support"
+ depends on FB && ARCH_PXA
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the built-in LCD controller in the Intel
+ PXA2x0 processor.
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called pxafb. If you want to compile it as a module,
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+
+ If unsure, say N.
+
+config FB_PXA_OVERLAY
+ bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer"
+ default n
+ depends on FB_PXA && (PXA27x || PXA3xx)
+
+config FB_PXA_SMARTPANEL
+ bool "PXA Smartpanel LCD support"
+ default n
+ depends on FB_PXA
+
+config FB_PXA_PARAMETERS
+ bool "PXA LCD command line parameters"
+ default n
+ depends on FB_PXA
+ ---help---
+ Enable the use of kernel command line or module parameters
+ to configure the physical properties of the LCD panel when
+ using the PXA LCD driver.
+
+ This option allows you to override the panel parameters
+ supplied by the platform in order to support multiple
+ different models of flatpanel. If you will only be using a
+ single model of flatpanel then you can safely leave this
+ option disabled.
+
+ <file:Documentation/fb/pxafb.txt> describes the available parameters.
+
+config PXA3XX_GCU
+ tristate "PXA3xx 2D graphics accelerator driver"
+ depends on FB_PXA
+ help
+ Kernelspace driver for the 2D graphics controller unit (GCU)
+ found on PXA3xx processors. There is a counterpart driver in the
+ DirectFB suite, see http://www.directfb.org/
+
+ If you compile this as a module, it will be called pxa3xx_gcu.
+
+config FB_MBX
+ tristate "2700G LCD framebuffer support"
+ depends on FB && ARCH_PXA
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Framebuffer driver for the Intel 2700G (Marathon) Graphics
+ Accelerator
+
+config FB_MBX_DEBUG
+ bool "Enable debugging info via debugfs"
+ depends on FB_MBX && DEBUG_FS
+ default n
+ ---help---
+ Enable this if you want debugging information using the debug
+ filesystem (debugfs)
+
+ If unsure, say N.
+
+config FB_FSL_DIU
+ tristate "Freescale DIU framebuffer support"
+ depends on FB && FSL_SOC
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select PPC_LIB_RHEAP
+ ---help---
+ Framebuffer driver for the Freescale SoC DIU
+
+config FB_W100
+ tristate "W100 frame buffer support"
+ depends on FB && ARCH_PXA
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
+ It can also drive the w3220 chip found on iPAQ hx4700.
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called w100fb. If you want to compile it as a module,
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+
+ If unsure, say N.
+
+config FB_SH_MOBILE_LCDC
+ tristate "SuperH Mobile LCDC framebuffer support"
+ depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ select FB_BACKLIGHT
+ select SH_MIPI_DSI if SH_LCD_MIPI_DSI
+ ---help---
+ Frame buffer driver for the on-chip SH-Mobile LCD controller.
+
+config FB_SH_MOBILE_HDMI
+ tristate "SuperH Mobile HDMI controller support"
+ depends on FB_SH_MOBILE_LCDC
+ select FB_MODE_HELPERS
+ select SOUND
+ select SND
+ select SND_SOC
+ ---help---
+ Driver for the on-chip SH-Mobile HDMI controller.
+
+config FB_TMIO
+ tristate "Toshiba Mobile IO FrameBuffer support"
+ depends on FB && MFD_CORE
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the Toshiba Mobile IO integrated as found
+ on the Sharp SL-6000 series
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called tmiofb. If you want to compile it as a module,
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+
+ If unsure, say N.
+
+config FB_TMIO_ACCELL
+ bool "tmiofb acceleration"
+ depends on FB_TMIO
+ default y
+
+config FB_S3C
+ tristate "Samsung S3C framebuffer support"
+ depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \
+ ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the built-in FB controller in the Samsung
+ SoC line from the S3C2443 onwards, including the S3C2416, S3C2450,
+ and the S3C64XX series such as the S3C6400 and S3C6410.
+
+ These chips all have the same basic framebuffer design with the
+ actual capabilities depending on the chip. For instance the S3C6400
+ and S3C6410 support 4 hardware windows whereas the S3C24XX series
+ currently only have two.
+
+ Currently the support is only for the S3C6400 and S3C6410 SoCs.
+
+config FB_S3C_DEBUG_REGWRITE
+ bool "Debug register writes"
+ depends on FB_S3C
+ ---help---
+ Show all register writes via pr_debug()
+
+config FB_S3C2410
+ tristate "S3C2410 LCD framebuffer support"
+ depends on FB && ARCH_S3C24XX
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the built-in LCD controller in the Samsung
+ S3C2410 processor.
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called s3c2410fb. If you want to compile it as a module,
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+
+ If unsure, say N.
+config FB_S3C2410_DEBUG
+ bool "S3C2410 lcd debug messages"
+ depends on FB_S3C2410
+ help
+ Turn on debugging messages. Note that you can set/unset at run time
+ through sysfs
+
+config FB_NUC900
+ bool "NUC900 LCD framebuffer support"
+ depends on FB && ARCH_W90X900
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the built-in LCD controller in the Nuvoton
+ NUC900 processor
+
+config GPM1040A0_320X240
+ bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD"
+ depends on FB_NUC900
+
+config FB_SM501
+ tristate "Silicon Motion SM501 framebuffer support"
+ depends on FB && MFD_SM501
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the CRT and LCD controllers in the Silicon
+ Motion SM501.
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called sm501fb. If you want to compile it as a module,
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+
+ If unsure, say N.
+
+config FB_SMSCUFX
+ tristate "SMSC UFX6000/7000 USB Framebuffer support"
+ depends on FB && USB
+ select FB_MODE_HELPERS
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ ---help---
+ This is a kernel framebuffer driver for SMSC UFX USB devices.
+ Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
+ mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000
+ (USB 3.0) devices.
+ To compile as a module, choose M here: the module name is smscufx.
+
+config FB_UDL
+ tristate "Displaylink USB Framebuffer support"
+ depends on FB && USB
+ select FB_MODE_HELPERS
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ ---help---
+ This is a kernel framebuffer driver for DisplayLink USB devices.
+ Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
+ mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
+ To compile as a module, choose M here: the module name is udlfb.
+
+config FB_IBM_GXT4500
+ tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors"
+ depends on FB && PPC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Say Y here to enable support for the IBM GXT4000P/6000P and
+ GXT4500P/6500P display adaptor based on Raster Engine RC1000,
+ found on some IBM System P (pSeries) machines. This driver
+ doesn't use Geometry Engine GT1000.
+
+config FB_PS3
+ tristate "PS3 GPU framebuffer driver"
+ depends on FB && PS3_PS3AV
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
+ ---help---
+ Include support for the virtual frame buffer in the PS3 platform.
+
+config FB_PS3_DEFAULT_SIZE_M
+ int "PS3 default frame buffer size (in MiB)"
+ depends on FB_PS3
+ default 9
+ ---help---
+ This is the default size (in MiB) of the virtual frame buffer in
+ the PS3.
+ The default value can be overridden on the kernel command line
+ using the "ps3fb" option (e.g. "ps3fb=9M");
+
+config FB_XILINX
+ tristate "Xilinx frame buffer support"
+ depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Include support for the Xilinx ML300/ML403 reference design
+ framebuffer. ML300 carries a 640*480 LCD display on the board,
+ ML403 uses a standard DB15 VGA connector.
+
+config FB_GOLDFISH
+ tristate "Goldfish Framebuffer"
+ depends on FB && HAS_DMA
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Framebuffer driver for Goldfish Virtual Platform
+
+config FB_COBALT
+ tristate "Cobalt server LCD frame buffer support"
+ depends on FB && (MIPS_COBALT || MIPS_SEAD3)
+
+config FB_SH7760
+ bool "SH7760/SH7763/SH7720/SH7721 LCDC support"
+ depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \
+ || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Support for the SH7760/SH7763/SH7720/SH7721 integrated
+ (D)STN/TFT LCD Controller.
+ Supports display resolutions up to 1024x1024 pixel, grayscale and
+ color operation, with depths ranging from 1 bpp to 8 bpp monochrome
+ and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for
+ panels <= 320 pixel horizontal resolution.
+
+config FB_DA8XX
+ tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support"
+ depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_CFB_REV_PIXELS_IN_BYTE
+ select FB_MODE_HELPERS
+ select VIDEOMODE_HELPERS
+ ---help---
+ This is the frame buffer device driver for the TI LCD controller
+ found on DA8xx/OMAP-L1xx/AM335x SoCs.
+ If unsure, say N.
+
+config FB_VIRTUAL
+ tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
+ depends on FB
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ ---help---
+ This is a `virtual' frame buffer device. It operates on a chunk of
+ unswappable kernel memory instead of on the memory of a graphics
+ board. This means you cannot see any output sent to this frame
+ buffer device, while it does consume precious memory. The main use
+ of this frame buffer device is testing and debugging the frame
+ buffer subsystem. Do NOT enable it for normal systems! To protect
+ the innocent, it has to be enabled explicitly at boot time using the
+ kernel option `video=vfb:'.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vfb. In order to load it, you must use
+ the vfb_enable=1 option.
+
+ If unsure, say N.
+
+config XEN_FBDEV_FRONTEND
+ tristate "Xen virtual frame buffer support"
+ depends on FB && XEN
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC
+ select XEN_XENBUS_FRONTEND
+ default y
+ help
+ This driver implements the front-end of the Xen virtual
+ frame buffer driver. It communicates with a back-end
+ in another domain.
+
+config FB_METRONOME
+ tristate "E-Ink Metronome/8track controller support"
+ depends on FB
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ help
+ This driver implements support for the E-Ink Metronome
+ controller. The pre-release name for this device was 8track
+ and could also have been called by some vendors as PVI-nnnn.
+
+config FB_MB862XX
+ tristate "Fujitsu MB862xx GDC support"
+ depends on FB
+ depends on PCI || (OF && PPC)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers.
+
+choice
+ prompt "GDC variant"
+ depends on FB_MB862XX
+
+config FB_MB862XX_PCI_GDC
+ bool "Carmine/Coral-P(A) GDC"
+ depends on PCI
+ ---help---
+ This enables framebuffer support for Fujitsu Carmine/Coral-P(A)
+ PCI graphics controller devices.
+
+config FB_MB862XX_LIME
+ bool "Lime GDC"
+ depends on OF && PPC
+ select FB_FOREIGN_ENDIAN
+ select FB_LITTLE_ENDIAN
+ ---help---
+ Framebuffer support for Fujitsu Lime GDC on host CPU bus.
+
+endchoice
+
+config FB_MB862XX_I2C
+ bool "Support I2C bus on MB862XX GDC"
+ depends on FB_MB862XX && I2C
+ default y
+ help
+ Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter
+ driver to support accessing I2C devices on controller's I2C bus.
+ These are usually some video decoder chips.
+
+config FB_EP93XX
+ tristate "EP93XX frame buffer support"
+ depends on FB && ARCH_EP93XX
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Framebuffer driver for the Cirrus Logic EP93XX series of processors.
+ This driver is also available as a module. The module will be called
+ ep93xx-fb.
+
+config FB_PRE_INIT_FB
+ bool "Don't reinitialize, use bootloader's GDC/Display configuration"
+ depends on FB && FB_MB862XX_LIME
+ ---help---
+ Select this option if display contents should be inherited as set by
+ the bootloader.
+
+config FB_MSM
+ tristate "MSM Framebuffer support"
+ depends on FB && ARCH_MSM
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+
+config FB_MX3
+ tristate "MX3 Framebuffer support"
+ depends on FB && MX3_IPU
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ default y
+ help
+ This is a framebuffer device for the i.MX31 LCD Controller. So
+ far only synchronous displays are supported. If you plan to use
+ an LCD display with your i.MX31 system, say Y here.
+
+config FB_BROADSHEET
+ tristate "E-Ink Broadsheet/Epson S1D13521 controller support"
+ depends on FB
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ help
+ This driver implements support for the E-Ink Broadsheet
+ controller. The release name for this device was Epson S1D13521
+ and could also have been called by other names when coupled with
+ a bridge adapter.
+
+config FB_AUO_K190X
+ tristate "AUO-K190X EPD controller support"
+ depends on FB
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ help
+ Provides support for epaper controllers from the K190X series
+ of AUO. These controllers can be used to drive epaper displays
+ from Sipix.
+
+ This option enables the common support, shared by the individual
+ controller drivers. You will also have to enable the driver
+ for the controller type used in your device.
+
+config FB_AUO_K1900
+ tristate "AUO-K1900 EPD controller support"
+ depends on FB && FB_AUO_K190X
+ help
+ This driver implements support for the AUO K1900 epd-controller.
+ This controller can drive Sipix epaper displays but can only do
+ serial updates, reducing the number of possible frames per second.
+
+config FB_AUO_K1901
+ tristate "AUO-K1901 EPD controller support"
+ depends on FB && FB_AUO_K190X
+ help
+ This driver implements support for the AUO K1901 epd-controller.
+ This controller can drive Sipix epaper displays and supports
+ concurrent updates, making higher frames per second possible.
+
+config FB_JZ4740
+ tristate "JZ4740 LCD framebuffer support"
+ depends on FB && MACH_JZ4740
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ help
+ Framebuffer support for the JZ4740 SoC.
+
+config FB_MXS
+ tristate "MXS LCD framebuffer support"
+ depends on FB && ARCH_MXS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MODE_HELPERS
+ select VIDEOMODE_HELPERS
+ help
+ Framebuffer support for the MXS SoC.
+
+config FB_PUV3_UNIGFX
+ tristate "PKUnity v3 Unigfx framebuffer support"
+ depends on FB && UNICORE32 && ARCH_PUV3
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ help
+ Choose this option if you want to use the Unigfx device as a
+ framebuffer device. Without the support of PCI & AGP.
+
+config FB_HYPERV
+ tristate "Microsoft Hyper-V Synthetic Video support"
+ depends on FB && HYPERV
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
+
+config FB_SIMPLE
+ bool "Simple framebuffer support"
+ depends on (FB = y)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Say Y if you want support for a simple frame-buffer.
+
+ This driver assumes that the display hardware has been initialized
+ before the kernel boots, and the kernel will simply render to the
+ pre-allocated frame buffer surface.
+
+ Configuration re: surface address, size, and format must be provided
+ through device tree, or plain old platform data.
+
+source "drivers/video/fbdev/omap/Kconfig"
+source "drivers/video/fbdev/omap2/Kconfig"
+source "drivers/video/fbdev/exynos/Kconfig"
+source "drivers/video/fbdev/mmp/Kconfig"
+
+config FB_SH_MOBILE_MERAM
+ tristate "SuperH Mobile MERAM read ahead support"
+ depends on (SUPERH || ARCH_SHMOBILE)
+ select GENERIC_ALLOCATOR
+ ---help---
+ Enable MERAM support for the SuperH controller.
+
+ This will allow for caching of the framebuffer to provide more
+ reliable access under heavy main memory bus traffic situations.
+ Up to 4 memory channels can be configured, allowing 4 RGB or
+ 2 YCbCr framebuffers to be configured.
+
+config FB_SSD1307
+ tristate "Solomon SSD1307 framebuffer support"
+ depends on FB && I2C
+ depends on OF
+ depends on GPIOLIB
+ select FB_SYS_FOPS
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_DEFERRED_IO
+ select PWM
+ help
+ This driver implements support for the Solomon SSD1307
+ OLED controller over I2C.
--- /dev/null
+# Makefile for the Linux video drivers.
+# 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
+# Rewritten to use lists instead of if-statements.
+
+# Each configuration option enables a list of files.
+
+obj-y += core/
+
+obj-$(CONFIG_EXYNOS_VIDEO) += exynos/
+
+obj-$(CONFIG_FB_MACMODES) += macmodes.o
+obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o
+
+# Hardware specific drivers go first
+obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
+obj-$(CONFIG_FB_ARC) += arcfb.o
+obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
+obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
+obj-$(CONFIG_FB_GRVGA) += grvga.o
+obj-$(CONFIG_FB_PM2) += pm2fb.o
+obj-$(CONFIG_FB_PM3) += pm3fb.o
+
+obj-$(CONFIG_FB_I740) += i740fb.o
+obj-$(CONFIG_FB_MATROX) += matrox/
+obj-$(CONFIG_FB_RIVA) += riva/
+obj-$(CONFIG_FB_NVIDIA) += nvidia/
+obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
+obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
+obj-$(CONFIG_FB_RADEON) += aty/
+obj-$(CONFIG_FB_SIS) += sis/
+obj-$(CONFIG_FB_VIA) += via/
+obj-$(CONFIG_FB_KYRO) += kyro/
+obj-$(CONFIG_FB_SAVAGE) += savage/
+obj-$(CONFIG_FB_GEODE) += geode/
+obj-$(CONFIG_FB_MBX) += mbx/
+obj-$(CONFIG_FB_NEOMAGIC) += neofb.o
+obj-$(CONFIG_FB_3DFX) += tdfxfb.o
+obj-$(CONFIG_FB_CONTROL) += controlfb.o
+obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
+obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o
+obj-$(CONFIG_FB_CT65550) += chipsfb.o
+obj-$(CONFIG_FB_IMSTT) += imsttfb.o
+obj-$(CONFIG_FB_FM2) += fm2fb.o
+obj-$(CONFIG_FB_VT8623) += vt8623fb.o
+obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
+obj-$(CONFIG_FB_LE80578) += vermilion/
+obj-$(CONFIG_FB_S3) += s3fb.o
+obj-$(CONFIG_FB_ARK) += arkfb.o
+obj-$(CONFIG_FB_STI) += stifb.o
+obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o
+obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o
+obj-$(CONFIG_FB_CG3) += cg3.o sbuslib.o
+obj-$(CONFIG_FB_BW2) += bw2.o sbuslib.o
+obj-$(CONFIG_FB_CG14) += cg14.o sbuslib.o
+obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o
+obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o
+obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o
+obj-$(CONFIG_FB_ACORN) += acornfb.o
+obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \
+ atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
+obj-$(CONFIG_FB_MAC) += macfb.o
+obj-$(CONFIG_FB_HECUBA) += hecubafb.o
+obj-$(CONFIG_FB_N411) += n411.o
+obj-$(CONFIG_FB_HGA) += hgafb.o
+obj-$(CONFIG_FB_XVR500) += sunxvr500.o
+obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o
+obj-$(CONFIG_FB_XVR1000) += sunxvr1000.o
+obj-$(CONFIG_FB_IGA) += igafb.o
+obj-$(CONFIG_FB_APOLLO) += dnfb.o
+obj-$(CONFIG_FB_Q40) += q40fb.o
+obj-$(CONFIG_FB_TGA) += tgafb.o
+obj-$(CONFIG_FB_HP300) += hpfb.o
+obj-$(CONFIG_FB_G364) += g364fb.o
+obj-$(CONFIG_FB_EP93XX) += ep93xx-fb.o
+obj-$(CONFIG_FB_SA1100) += sa1100fb.o
+obj-$(CONFIG_FB_HIT) += hitfb.o
+obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
+obj-$(CONFIG_FB_PVR2) += pvr2fb.o
+obj-$(CONFIG_FB_VOODOO1) += sstfb.o
+obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
+obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
+obj-$(CONFIG_FB_68328) += 68328fb.o
+obj-$(CONFIG_FB_GBE) += gbefb.o
+obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
+obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
+obj-$(CONFIG_FB_PXA) += pxafb.o
+obj-$(CONFIG_FB_PXA168) += pxa168fb.o
+obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o
+obj-$(CONFIG_MMP_DISP) += mmp/
+obj-$(CONFIG_FB_W100) += w100fb.o
+obj-$(CONFIG_FB_TMIO) += tmiofb.o
+obj-$(CONFIG_FB_AU1100) += au1100fb.o
+obj-$(CONFIG_FB_AU1200) += au1200fb.o
+obj-$(CONFIG_FB_VT8500) += vt8500lcdfb.o
+obj-$(CONFIG_FB_WM8505) += wm8505fb.o
+obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
+obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
+obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
+obj-$(CONFIG_FB_MAXINE) += maxinefb.o
+obj-$(CONFIG_FB_METRONOME) += metronomefb.o
+obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o
+obj-$(CONFIG_FB_AUO_K190X) += auo_k190x.o
+obj-$(CONFIG_FB_AUO_K1900) += auo_k1900fb.o
+obj-$(CONFIG_FB_AUO_K1901) += auo_k1901fb.o
+obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
+obj-$(CONFIG_FB_SH7760) += sh7760fb.o
+obj-$(CONFIG_FB_IMX) += imxfb.o
+obj-$(CONFIG_FB_S3C) += s3c-fb.o
+obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
+obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o
+obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o
+obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
+obj-$(CONFIG_FB_PS3) += ps3fb.o
+obj-$(CONFIG_FB_SM501) += sm501fb.o
+obj-$(CONFIG_FB_UDL) += udlfb.o
+obj-$(CONFIG_FB_SMSCUFX) += smscufx.o
+obj-$(CONFIG_FB_XILINX) += xilinxfb.o
+obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o
+obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o
+obj-$(CONFIG_FB_SH_MOBILE_MERAM) += sh_mobile_meram.o
+obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
+obj-$(CONFIG_FB_OMAP) += omap/
+obj-y += omap2/
+obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
+obj-$(CONFIG_FB_CARMINE) += carminefb.o
+obj-$(CONFIG_FB_MB862XX) += mb862xx/
+obj-$(CONFIG_FB_MSM) += msm/
+obj-$(CONFIG_FB_NUC900) += nuc900fb.o
+obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
+obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
+obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o
+obj-$(CONFIG_FB_OPENCORES) += ocfb.o
+
+# Platform or fallback drivers go here
+obj-$(CONFIG_FB_UVESA) += uvesafb.o
+obj-$(CONFIG_FB_VESA) += vesafb.o
+obj-$(CONFIG_FB_EFI) += efifb.o
+obj-$(CONFIG_FB_VGA16) += vga16fb.o
+obj-$(CONFIG_FB_OF) += offb.o
+obj-$(CONFIG_FB_BF537_LQ035) += bf537-lq035.o
+obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o
+obj-$(CONFIG_FB_BFIN_LQ035Q1) += bfin-lq035q1-fb.o
+obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o
+obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o
+obj-$(CONFIG_FB_MX3) += mx3fb.o
+obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o
+obj-$(CONFIG_FB_MXS) += mxsfb.o
+obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o
+obj-$(CONFIG_FB_SIMPLE) += simplefb.o
+
+# the test framebuffer is last
+obj-$(CONFIG_FB_VIRTUAL) += vfb.o
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/string.h>
-#include "../fb_draw.h"
+#include "../core/fb_draw.h"
#include <asm/io.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
+#include <linux/gpio.h>
#include <asm/blackfin.h>
#include <asm/irq.h>
#include <asm/dpmc.h>
#include <asm/dma-mapping.h>
#include <asm/dma.h>
-#include <asm/gpio.h>
#include <asm/portmux.h>
#include <mach/bf54x-lq043.h>
--- /dev/null
+obj-y += fb_notify.o
+obj-$(CONFIG_FB) += fb.o
+fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
+ modedb.o fbcvt.o
+fb-objs := $(fb-y)
+
+obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
+obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
+obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
+obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o
+obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o
+obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
+obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o
+obj-$(CONFIG_FB_SVGALIB) += svgalib.o
+obj-$(CONFIG_FB_DDC) += fb_ddc.o
+obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
#include <linux/i2c-algo-bit.h>
#include <linux/slab.h>
-#include "edid.h"
+#include "../edid.h"
#define DDC_ADDR 0x50
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#endif
-#include "edid.h"
+#include "../edid.h"
/*
* EDID parser
(green << info->var.green.offset) |
(blue << info->var.blue.offset);
- switch (info->var.bits_per_pixel) {
- case 16:
- ((u16 *) (info->pseudo_palette))[regno] = v;
- break;
- case 24:
- case 32:
- ((u32 *) (info->pseudo_palette))[regno] = v;
- break;
- }
+ ((u32 *) (info->pseudo_palette))[regno] = v;
if (palette[0] != 0x4000) {
update_hw = 1;
palette[0] = 0x4000;
Marvell Display Subsystem support.
if MMP_DISP
-source "drivers/video/mmp/hw/Kconfig"
-source "drivers/video/mmp/panel/Kconfig"
-source "drivers/video/mmp/fb/Kconfig"
+source "drivers/video/fbdev/mmp/hw/Kconfig"
+source "drivers/video/fbdev/mmp/panel/Kconfig"
+source "drivers/video/fbdev/mmp/fb/Kconfig"
endif
--- /dev/null
+config OMAP2_VRFB
+ bool
+
+if ARCH_OMAP2PLUS
+
+source "drivers/video/fbdev/omap2/dss/Kconfig"
+source "drivers/video/fbdev/omap2/omapfb/Kconfig"
+source "drivers/video/fbdev/omap2/displays-new/Kconfig"
+
+endif
void __iomem *base;
int irq;
+ irq_handler_t user_handler;
+ void *user_data;
unsigned long core_clk_rate;
unsigned long tv_pclk_rate;
u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
const struct dispc_features *feat;
+
+ bool is_enabled;
} dispc;
enum omap_color_component {
DISPC_MGR_FLD_NUM,
};
+struct dispc_reg_field {
+ u16 reg;
+ u8 high;
+ u8 low;
+};
+
static const struct {
const char *name;
u32 vsync_irq;
u32 framedone_irq;
u32 sync_lost_irq;
- struct reg_field reg_desc[DISPC_MGR_FLD_NUM];
+ struct dispc_reg_field reg_desc[DISPC_MGR_FLD_NUM];
} mgr_desc[] = {
[OMAP_DSS_CHANNEL_LCD] = {
.name = "LCD",
static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
{
- const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
+ const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
return REG_GET(rfld.reg, rfld.high, rfld.low);
}
static void mgr_fld_write(enum omap_channel channel,
enum mgr_reg_fields regfld, int val) {
- const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
+ const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
}
return 0;
}
+static irqreturn_t dispc_irq_handler(int irq, void *arg)
+{
+ if (!dispc.is_enabled)
+ return IRQ_NONE;
+
+ return dispc.user_handler(irq, dispc.user_data);
+}
+
int dispc_request_irq(irq_handler_t handler, void *dev_id)
{
- return devm_request_irq(&dispc.pdev->dev, dispc.irq, handler,
- IRQF_SHARED, "OMAP DISPC", dev_id);
+ int r;
+
+ if (dispc.user_handler != NULL)
+ return -EBUSY;
+
+ dispc.user_handler = handler;
+ dispc.user_data = dev_id;
+
+ /* ensure the dispc_irq_handler sees the values above */
+ smp_wmb();
+
+ r = devm_request_irq(&dispc.pdev->dev, dispc.irq, dispc_irq_handler,
+ IRQF_SHARED, "OMAP DISPC", &dispc);
+ if (r) {
+ dispc.user_handler = NULL;
+ dispc.user_data = NULL;
+ }
+
+ return r;
}
EXPORT_SYMBOL(dispc_request_irq);
void dispc_free_irq(void *dev_id)
{
- devm_free_irq(&dispc.pdev->dev, dispc.irq, dev_id);
+ devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc);
+
+ dispc.user_handler = NULL;
+ dispc.user_data = NULL;
}
EXPORT_SYMBOL(dispc_free_irq);
static int dispc_runtime_suspend(struct device *dev)
{
+ dispc.is_enabled = false;
+ /* ensure the dispc_irq_handler sees the is_enabled value */
+ smp_wmb();
+ /* wait for current handler to finish before turning the DISPC off */
+ synchronize_irq(dispc.irq);
+
dispc_save_context();
return 0;
* _omap_dispc_initial_config(). We can thus use it to detect if
* we have lost register context.
*/
- if (REG_GET(DISPC_CONFIG, 2, 1) == OMAP_DSS_LOAD_FRAME_ONLY)
- return 0;
+ if (REG_GET(DISPC_CONFIG, 2, 1) != OMAP_DSS_LOAD_FRAME_ONLY) {
+ _omap_dispc_initial_config();
- _omap_dispc_initial_config();
+ dispc_restore_context();
+ }
- dispc_restore_context();
+ dispc.is_enabled = true;
+ /* ensure the dispc_irq_handler sees the is_enabled value */
+ smp_wmb();
return 0;
}
int irq;
+ bool is_enabled;
+
struct clk *dss_clk;
struct clk *sys_clk;
dsidev = (struct platform_device *) arg;
dsi = dsi_get_dsidrv_data(dsidev);
+ if (!dsi->is_enabled)
+ return IRQ_NONE;
+
spin_lock(&dsi->irq_lock);
irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS);
static int dsi_runtime_suspend(struct device *dev)
{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
+
+ dsi->is_enabled = false;
+ /* ensure the irq handler sees the is_enabled value */
+ smp_wmb();
+ /* wait for current handler to finish before turning the DSI off */
+ synchronize_irq(dsi->irq);
+
dispc_runtime_put();
return 0;
static int dsi_runtime_resume(struct device *dev)
{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
int r;
r = dispc_runtime_get();
if (r)
return r;
+ dsi->is_enabled = true;
+ /* ensure the irq handler sees the is_enabled value */
+ smp_wmb();
+
return 0;
}
fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul);
for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
- fck = prate / fckd * m;
+ fck = DIV_ROUND_UP(prate, fckd) * m;
if (func(fck, data))
return true;
fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
max_dss_fck);
- fck = prate / fck_div * dss.feat->dss_fck_multiplier;
+ fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier;
}
r = dss_set_fck_rate(fck);
u16 lp_clk_div;
};
-struct reg_field {
- u16 reg;
- u8 high;
- u8 low;
-};
-
struct dss_lcd_mgr_config {
enum dss_io_pad_mode io_pad_mode;
case 96000:
case 192000:
if (deep_color == 125)
- if (pclk == 27027 || pclk == 74250)
+ if (pclk == 27027000 || pclk == 74250000)
deep_color_correct = true;
if (deep_color == 150)
- if (pclk == 27027)
+ if (pclk == 27027000)
deep_color_correct = true;
break;
case 44100:
case 88200:
case 176400:
if (deep_color == 125)
- if (pclk == 27027)
+ if (pclk == 27027000)
deep_color_correct = true;
break;
default:
}
}
/* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
- *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
+ *cts = (pclk/1000) * (*n / 128) * deep_color / (sample_freq / 10);
return 0;
}
#include <linux/module.h>
#include <linux/fb.h>
#include <linux/platform_device.h>
-#include "fb_draw.h"
+#include "core/fb_draw.h"
#define GE_COMMAND_OFF 0x00
#define GE_DEPTH_OFF 0x04
+++ /dev/null
-config OMAP2_VRFB
- bool
-
-if ARCH_OMAP2PLUS
-
-source "drivers/video/omap2/dss/Kconfig"
-source "drivers/video/omap2/omapfb/Kconfig"
-source "drivers/video/omap2/displays-new/Kconfig"
-
-endif
struct pci_dev *pdev;
struct tsi148_driver *bridge;
- pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
+ pdev = to_pci_dev(tsi148_bridge->parent);
bridge = tsi148_bridge->driver_priv;
iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
if (sync != 0) {
- pdev = container_of(tsi148_bridge->parent,
- struct pci_dev, dev);
-
+ pdev = to_pci_dev(tsi148_bridge->parent);
synchronize_irq(pdev->irq);
}
} else {
reg_join(vme_bound_high, vme_bound_low, &vme_bound);
reg_join(pci_offset_high, pci_offset_low, &pci_offset);
- *pci_base = (dma_addr_t)vme_base + pci_offset;
+ *pci_base = (dma_addr_t)(*vme_base + pci_offset);
*enabled = 0;
*aspace = 0;
tsi148_bridge = image->parent;
- pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
+ pdev = to_pci_dev(tsi148_bridge->parent);
existing_size = (unsigned long long)(image->bus_resource.end -
image->bus_resource.start);
unsigned long long pci_bound, vme_offset, pci_base;
struct vme_bridge *tsi148_bridge;
struct tsi148_driver *bridge;
+ struct pci_bus_region region;
+ struct pci_dev *pdev;
tsi148_bridge = image->parent;
bridge = tsi148_bridge->driver_priv;
+ pdev = to_pci_dev(tsi148_bridge->parent);
+
/* Verify input data */
if (vme_base & 0xFFFF) {
dev_err(tsi148_bridge->parent, "Invalid VME Window "
pci_bound = 0;
vme_offset = 0;
} else {
- pci_base = (unsigned long long)image->bus_resource.start;
+ pcibios_resource_to_bus(pdev->bus, ®ion,
+ &image->bus_resource);
+ pci_base = region.start;
/*
* Bound address is a valid address for the window, adjust
struct pci_dev *pdev;
/* Find pci_dev container of dev */
- pdev = container_of(parent, struct pci_dev, dev);
+ pdev = to_pci_dev(parent);
return pci_alloc_consistent(pdev, size, dma);
}
struct pci_dev *pdev;
/* Find pci_dev container of dev */
- pdev = container_of(parent, struct pci_dev, dev);
+ pdev = to_pci_dev(parent);
pci_free_consistent(pdev, size, vaddr, dma);
}
return err;
}
-/*
- * Handle sysfs file creation and removal here, before userspace is told that
- * the device is added / removed from the system
- */
-static int w1_bus_notify(struct notifier_block *nb, unsigned long action,
- void *data)
+static int w1_family_notify(unsigned long action, struct w1_slave *sl)
{
- struct device *dev = data;
- struct w1_slave *sl;
struct w1_family_ops *fops;
int err;
- /*
- * Only care about slave devices at the moment. Yes, we should use a
- * separate "type" for this, but for now, look at the release function
- * to know which type it is...
- */
- if (dev->release != w1_slave_release)
- return 0;
-
- sl = dev_to_w1_slave(dev);
fops = sl->family->fops;
if (!fops)
return 0;
}
-static struct notifier_block w1_bus_nb = {
- .notifier_call = w1_bus_notify,
-};
-
static int __w1_attach_slave_device(struct w1_slave *sl)
{
int err;
dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__,
dev_name(&sl->dev), sl);
+ /* suppress for w1_family_notify before sending KOBJ_ADD */
+ dev_set_uevent_suppress(&sl->dev, true);
+
err = device_register(&sl->dev);
if (err < 0) {
dev_err(&sl->dev,
dev_name(&sl->dev), err);
return err;
}
-
+ w1_family_notify(BUS_NOTIFY_ADD_DEVICE, sl);
dev_set_uevent_suppress(&sl->dev, false);
kobject_uevent(&sl->dev.kobj, KOBJ_ADD);
msg.type = W1_SLAVE_REMOVE;
w1_netlink_send(sl->master, &msg);
+ w1_family_notify(BUS_NOTIFY_DEL_DEVICE, sl);
device_unregister(&sl->dev);
#ifdef DEBUG
memset(sl, 0, sizeof(*sl));
goto err_out_exit_init;
}
- retval = bus_register_notifier(&w1_bus_type, &w1_bus_nb);
- if (retval)
- goto err_out_bus_unregister;
-
retval = driver_register(&w1_master_driver);
if (retval) {
printk(KERN_ERR
struct w1_netlink_msg *w;
u32 *id;
- if (mcmd->type != W1_LIST_MASTERS) {
- printk(KERN_NOTICE "%s: msg: %x.%x, wrong type: %u, len: %u.\n",
- __func__, msg->id.idx, msg->id.val, mcmd->type, mcmd->len);
- return -EPROTO;
- }
-
cn = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!cn)
return -ENOMEM;
w1_netlink_send_error(&node->block->msg, node->m, cmd,
node->block->portid, err);
+ /* ref taken in w1_search_slave or w1_search_master_id when building
+ * the block
+ */
if (sl)
w1_unref_slave(sl);
else
msg_len = msg->len;
while (msg_len && !err) {
- struct w1_reg_num id;
- u16 mlen = m->len;
dev = NULL;
sl = NULL;
- memcpy(&id, m->id.id, sizeof(id));
-#if 0
- printk("%s: %02x.%012llx.%02x: type=%02x, len=%u.\n",
- __func__, id.family, (unsigned long long)id.id, id.crc, m->type, m->len);
-#endif
if (m->len + sizeof(struct w1_netlink_msg) > msg_len) {
err = -E2BIG;
break;
}
+ /* execute on this thread, no need to process later */
+ if (m->type == W1_LIST_MASTERS) {
+ err = w1_process_command_root(msg, m, nsp->portid);
+ goto out_cont;
+ }
+
+ /* All following message types require additional data,
+ * check here before references are taken.
+ */
+ if (!m->len) {
+ err = -EPROTO;
+ goto out_cont;
+ }
+
+ /* both search calls take reference counts */
if (m->type == W1_MASTER_CMD) {
dev = w1_search_master_id(m->id.mst.id);
} else if (m->type == W1_SLAVE_CMD) {
- sl = w1_search_slave(&id);
+ sl = w1_search_slave((struct w1_reg_num *)m->id.id);
if (sl)
dev = sl->master;
} else {
- err = w1_process_command_root(msg, m, nsp->portid);
+ printk(KERN_NOTICE
+ "%s: msg: %x.%x, wrong type: %u, len: %u.\n",
+ __func__, msg->id.idx, msg->id.val,
+ m->type, m->len);
+ err = -EPROTO;
goto out_cont;
}
}
err = 0;
- if (!mlen)
- goto out_cont;
atomic_inc(&block->refcnt);
node->async.cb = w1_process_cb;
if (err)
w1_netlink_send_error(msg, m, NULL, nsp->portid, err);
msg_len -= sizeof(struct w1_netlink_msg) + m->len;
- m = (struct w1_netlink_msg *)(((u8 *)m) + sizeof(struct w1_netlink_msg) + m->len);
+ m = (struct w1_netlink_msg *)(((u8 *)m) +
+ sizeof(struct w1_netlink_msg) + m->len);
/*
* Let's allow requests for nonexisting devices.
void (*cb)(void);
};
+static int poweroff_nb(struct notifier_block *cb, unsigned long code, void *unused)
+{
+ switch (code) {
+ case SYS_DOWN:
+ case SYS_HALT:
+ case SYS_POWER_OFF:
+ shutting_down = SHUTDOWN_POWEROFF;
+ default:
+ break;
+ }
+ return NOTIFY_DONE;
+}
static void do_poweroff(void)
{
- shutting_down = SHUTDOWN_POWEROFF;
- orderly_poweroff(false);
+ switch (system_state) {
+ case SYSTEM_BOOTING:
+ orderly_poweroff(true);
+ break;
+ case SYSTEM_RUNNING:
+ orderly_poweroff(false);
+ break;
+ default:
+ /* Don't do it when we are halting/rebooting. */
+ pr_info("Ignoring Xen toolstack shutdown.\n");
+ break;
+ }
}
static void do_reboot(void)
.callback = shutdown_handler
};
+static struct notifier_block xen_reboot_nb = {
+ .notifier_call = poweroff_nb,
+};
+
static int setup_shutdown_watcher(void)
{
int err;
return err;
}
+
#ifdef CONFIG_MAGIC_SYSRQ
err = register_xenbus_watch(&sysrq_watch);
if (err) {
if (!xen_domain())
return -ENODEV;
register_xenstore_notifier(&xenstore_notifier);
+ register_reboot_notifier(&xen_reboot_nb);
return 0;
}
if (result == 0) {
for (i = 0; i < op->value; i++) {
op->msix_entries[i].entry = entries[i].entry;
- if (entries[i].vector)
+ if (entries[i].vector) {
op->msix_entries[i].vector =
xen_pirq_from_irq(entries[i].vector);
if (unlikely(verbose_request))
"MSI-X[%d]: %d\n",
pci_name(dev), i,
op->msix_entries[i].vector);
+ }
}
} else
pr_warn_ratelimited("%s: error enabling MSI-X for guest %u: err %d!\n",
/* Publish this device. */
if (!err)
err = publish_cb(pdev, 0, 0, PCI_DEVFN(slot, func), devid);
+ else
+ kfree(dev_entry);
out:
return err;
#include <xen/xenbus.h>
#include <xen/xen.h>
#include "xenbus_comms.h"
+#include "xenbus_probe.h"
struct xs_stored_msg {
struct list_head list;
return xsd_errors[i].errnum;
}
+static bool xenbus_ok(void)
+{
+ switch (xen_store_domain_type) {
+ case XS_LOCAL:
+ switch (system_state) {
+ case SYSTEM_POWER_OFF:
+ case SYSTEM_RESTART:
+ case SYSTEM_HALT:
+ return false;
+ default:
+ break;
+ }
+ return true;
+ case XS_PV:
+ case XS_HVM:
+ /* FIXME: Could check that the remote domain is alive,
+ * but it is normally initial domain. */
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
{
struct xs_stored_msg *msg;
while (list_empty(&xs_state.reply_list)) {
spin_unlock(&xs_state.reply_lock);
- /* XXX FIXME: Avoid synchronous wait for response here. */
- wait_event(xs_state.reply_waitq,
- !list_empty(&xs_state.reply_list));
+ if (xenbus_ok())
+ /* XXX FIXME: Avoid synchronous wait for response here. */
+ wait_event_timeout(xs_state.reply_waitq,
+ !list_empty(&xs_state.reply_list),
+ msecs_to_jiffies(500));
+ else {
+ /*
+ * If we are in the process of being shut-down there is
+ * no point of trying to contact XenBus - it is either
+ * killed (xenstored application) or the other domain
+ * has been killed or is unreachable.
+ */
+ return ERR_PTR(-EIO);
+ }
spin_lock(&xs_state.reply_lock);
}
mutex_unlock(&xs_state.request_mutex);
+ if (IS_ERR(ret))
+ return ret;
+
if ((msg->type == XS_TRANSACTION_END) ||
((req_msg.type == XS_TRANSACTION_START) &&
(msg->type == XS_ERROR)))
--------------------------------------------------------------------------
-Driver: ip2 -- Computone IntelliPort Plus serial device
-
-File: intelliport2.bin
-
-Licence: Unknown
-
-Found in hex form in kernel source.
-
---------------------------------------------------------------------------
-
Driver: CPiA2 -- cameras based on Vision's CPiA2
File: cpia2/stv0672_vp4.bin
#define btrfs_raw_test_opt(o, opt) ((o) & BTRFS_MOUNT_##opt)
#define btrfs_test_opt(root, opt) ((root)->fs_info->mount_opt & \
BTRFS_MOUNT_##opt)
+#define btrfs_set_and_info(root, opt, fmt, args...) \
+{ \
+ if (!btrfs_test_opt(root, opt)) \
+ btrfs_info(root->fs_info, fmt, ##args); \
+ btrfs_set_opt(root->fs_info->mount_opt, opt); \
+}
+
+#define btrfs_clear_and_info(root, opt, fmt, args...) \
+{ \
+ if (btrfs_test_opt(root, opt)) \
+ btrfs_info(root->fs_info, fmt, ##args); \
+ btrfs_clear_opt(root->fs_info->mount_opt, opt); \
+}
+
/*
* Inode flags
*/
printk(KERN_ERR "BTRFS: failed to read log tree\n");
free_extent_buffer(log_tree_root->node);
kfree(log_tree_root);
- goto fail_trans_kthread;
+ goto fail_qgroup;
}
/* returns with log_tree_root freed on success */
ret = btrfs_recover_log_trees(log_tree_root);
"Failed to recover log tree");
free_extent_buffer(log_tree_root->node);
kfree(log_tree_root);
- goto fail_trans_kthread;
+ goto fail_qgroup;
}
if (sb->s_flags & MS_RDONLY) {
ret = btrfs_commit_super(tree_root);
if (ret)
- goto fail_trans_kthread;
+ goto fail_qgroup;
}
}
ret = btrfs_find_orphan_roots(tree_root);
if (ret)
- goto fail_trans_kthread;
+ goto fail_qgroup;
if (!(sb->s_flags & MS_RDONLY)) {
ret = btrfs_cleanup_fs_roots(fs_info);
if (ret)
- goto fail_trans_kthread;
+ goto fail_qgroup;
ret = btrfs_recover_relocation(tree_root);
if (ret < 0) {
ret = 0;
}
if (ret) {
+ key.objectid = bytenr;
key.type = BTRFS_EXTENT_ITEM_KEY;
key.offset = num_bytes;
btrfs_release_path(path);
return extended_to_chunk(flags | tmp);
}
-static u64 get_alloc_profile(struct btrfs_root *root, u64 flags)
+static u64 get_alloc_profile(struct btrfs_root *root, u64 orig_flags)
{
unsigned seq;
+ u64 flags;
do {
+ flags = orig_flags;
seq = read_seqbegin(&root->fs_info->profiles_lock);
if (flags & BTRFS_BLOCK_GROUP_DATA)
if (ret > 0 && skinny_metadata) {
skinny_metadata = false;
+ key.objectid = bytenr;
key.type = BTRFS_EXTENT_ITEM_KEY;
key.offset = num_bytes;
btrfs_release_path(path);
if (start > key.offset && end < extent_end) {
BUG_ON(del_nr > 0);
if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
- ret = -EINVAL;
+ ret = -EOPNOTSUPP;
break;
}
*/
if (start <= key.offset && end < extent_end) {
if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
- ret = -EINVAL;
+ ret = -EOPNOTSUPP;
break;
}
if (start > key.offset && end >= extent_end) {
BUG_ON(del_nr > 0);
if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
- ret = -EINVAL;
+ ret = -EOPNOTSUPP;
break;
}
start_pos = round_down(pos, root->sectorsize);
if (start_pos > i_size_read(inode)) {
/* Expand hole size to cover write data, preventing empty gap */
- end_pos = round_up(pos + iov->iov_len, root->sectorsize);
+ end_pos = round_up(pos + count, root->sectorsize);
err = btrfs_cont_expand(inode, i_size_read(inode), end_pos);
if (err) {
mutex_unlock(&inode->i_mutex);
tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu\n",
root->root_key.objectid);
- BUG_ON(IS_ERR(tsk)); /* -ENOMEM */
+ if (IS_ERR(tsk)) {
+ btrfs_warn(root->fs_info, "failed to start inode caching task");
+ btrfs_clear_and_info(root, CHANGE_INODE_CACHE,
+ "disabling inode map caching");
+ }
}
int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid)
void btrfs_return_ino(struct btrfs_root *root, u64 objectid)
{
- struct btrfs_free_space_ctl *ctl = root->free_ino_ctl;
struct btrfs_free_space_ctl *pinned = root->free_ino_pinned;
if (!btrfs_test_opt(root, INODE_MAP_CACHE))
return;
-
again:
if (root->cached == BTRFS_CACHE_FINISHED) {
- __btrfs_add_free_space(ctl, objectid, 1);
+ __btrfs_add_free_space(pinned, objectid, 1);
} else {
- /*
- * If we are in the process of caching free ino chunks,
- * to avoid adding the same inode number to the free_ino
- * tree twice due to cross transaction, we'll leave it
- * in the pinned tree until a transaction is committed
- * or the caching work is done.
- */
-
down_write(&root->fs_info->commit_root_sem);
spin_lock(&root->cache_lock);
if (root->cached == BTRFS_CACHE_FINISHED) {
start_caching(root);
- if (objectid <= root->cache_progress ||
- objectid >= root->highest_objectid)
- __btrfs_add_free_space(ctl, objectid, 1);
- else
- __btrfs_add_free_space(pinned, objectid, 1);
+ __btrfs_add_free_space(pinned, objectid, 1);
up_write(&root->fs_info->commit_root_sem);
}
new_key.offset + datal,
1);
if (ret) {
- if (ret != -EINVAL)
+ if (ret != -EOPNOTSUPP)
btrfs_abort_transaction(trans,
root, ret);
btrfs_end_transaction(trans, root);
new_key.offset + datal,
1);
if (ret) {
- if (ret != -EINVAL)
+ if (ret != -EOPNOTSUPP)
btrfs_abort_transaction(trans,
root, ret);
btrfs_end_transaction(trans, root);
if (p->buf_len >= len)
return 0;
+ if (len > PATH_MAX) {
+ WARN_ON(1);
+ return -ENOMEM;
+ }
+
path_len = p->end - p->start;
old_buf_len = p->buf_len;
{Opt_err, NULL},
};
-#define btrfs_set_and_info(root, opt, fmt, args...) \
-{ \
- if (!btrfs_test_opt(root, opt)) \
- btrfs_info(root->fs_info, fmt, ##args); \
- btrfs_set_opt(root->fs_info->mount_opt, opt); \
-}
-
-#define btrfs_clear_and_info(root, opt, fmt, args...) \
-{ \
- if (btrfs_test_opt(root, opt)) \
- btrfs_info(root->fs_info, fmt, ##args); \
- btrfs_clear_opt(root->fs_info->mount_opt, opt); \
-}
-
/*
* Regular mount options parser. Everything that is needed only when
* reading in a new superblock is parsed here.
return ERR_PTR(-ENOMEM);
mnt = vfs_kern_mount(&btrfs_fs_type, flags, device_name,
newargs);
- kfree(newargs);
if (PTR_RET(mnt) == -EBUSY) {
if (flags & MS_RDONLY) {
int r;
mnt = vfs_kern_mount(&btrfs_fs_type, flags | MS_RDONLY, device_name,
newargs);
- if (IS_ERR(mnt))
+ if (IS_ERR(mnt)) {
+ kfree(newargs);
return ERR_CAST(mnt);
+ }
r = btrfs_remount(mnt->mnt_sb, &flags, NULL);
if (r < 0) {
/* FIXME: release vfsmount mnt ??*/
+ kfree(newargs);
return ERR_PTR(r);
}
}
}
+ kfree(newargs);
+
if (IS_ERR(mnt))
return ERR_CAST(mnt);
if (!S_ISREG(inode->i_mode))
return -EOPNOTSUPP;
- if (IS_SWAPFILE(inode))
- return -ETXTBSY;
-
mutex_lock(&inode->i_mutex);
if (ceph_snap(inode) != CEPH_NOSNAP) {
cifs_set_oplock_level(cifs_inode, 0);
cifs_inode->delete_pending = false;
cifs_inode->invalid_mapping = false;
+ clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cifs_inode->flags);
+ clear_bit(CIFS_INODE_PENDING_WRITERS, &cifs_inode->flags);
+ clear_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cifs_inode->flags);
+ spin_lock_init(&cifs_inode->writers_lock);
+ cifs_inode->writers = 0;
cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
cifs_inode->server_eof = 0;
cifs_inode->uniqueid = 0;
unsigned long nr_segs, loff_t pos)
{
struct inode *inode = file_inode(iocb->ki_filp);
+ struct cifsInodeInfo *cinode = CIFS_I(inode);
ssize_t written;
int rc;
+ written = cifs_get_writer(cinode);
+ if (written)
+ return written;
+
written = generic_file_aio_write(iocb, iov, nr_segs, pos);
if (CIFS_CACHE_WRITE(CIFS_I(inode)))
- return written;
+ goto out;
rc = filemap_fdatawrite(inode->i_mapping);
if (rc)
cifs_dbg(FYI, "cifs_file_aio_write: %d rc on %p inode\n",
rc, inode);
+out:
+ cifs_put_writer(cinode);
return written;
}
/* verify the message */
int (*check_message)(char *, unsigned int);
bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
+ void (*downgrade_oplock)(struct TCP_Server_Info *,
+ struct cifsInodeInfo *, bool);
/* process transaction2 response */
bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *,
char *, int);
unsigned int epoch; /* used to track lease state changes */
bool delete_pending; /* DELETE_ON_CLOSE is set */
bool invalid_mapping; /* pagecache is invalid */
+ unsigned long flags;
+#define CIFS_INODE_PENDING_OPLOCK_BREAK (0) /* oplock break in progress */
+#define CIFS_INODE_PENDING_WRITERS (1) /* Writes in progress */
+#define CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2 (2) /* Downgrade oplock to L2 */
+ spinlock_t writers_lock;
+ unsigned int writers; /* Number of writers on this inode */
unsigned long time; /* jiffies of last update of inode */
u64 server_eof; /* current file size on server -- protected by i_lock */
u64 uniqueid; /* server inode number */
extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
int offset);
extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
+extern int cifs_get_writer(struct cifsInodeInfo *cinode);
+extern void cifs_put_writer(struct cifsInodeInfo *cinode);
+extern void cifs_done_oplock_break(struct cifsInodeInfo *cinode);
extern int cifs_unlock_range(struct cifsFileInfo *cfile,
struct file_lock *flock, const unsigned int xid);
extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile);
cifs_dbg(FYI, "ea length %d\n", list_len);
if (list_len <= 8) {
cifs_dbg(FYI, "empty EA list returned from server\n");
+ /* didn't find the named attribute */
+ if (ea_name)
+ rc = -ENODATA;
goto QAllEAsOut;
}
ssize_t err;
err = generic_write_sync(file, iocb->ki_pos - rc, rc);
- if (rc < 0)
+ if (err < 0)
rc = err;
}
} else {
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
ssize_t written;
+ written = cifs_get_writer(cinode);
+ if (written)
+ return written;
+
if (CIFS_CACHE_WRITE(cinode)) {
if (cap_unix(tcon->ses) &&
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))
- && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
- return generic_file_aio_write(iocb, iov, nr_segs, pos);
- return cifs_writev(iocb, iov, nr_segs, pos);
+ && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) {
+ written = generic_file_aio_write(
+ iocb, iov, nr_segs, pos);
+ goto out;
+ }
+ written = cifs_writev(iocb, iov, nr_segs, pos);
+ goto out;
}
/*
* For non-oplocked files in strict cache mode we need to write the data
inode);
cinode->oplock = 0;
}
+out:
+ cifs_put_writer(cinode);
return written;
}
cifs_uncached_readv_complete);
if (!rdata) {
rc = -ENOMEM;
- goto error;
+ break;
}
rc = cifs_read_allocate_pages(rdata, npages);
return rc;
}
+static int
+cifs_pending_writers_wait(void *unused)
+{
+ schedule();
+ return 0;
+}
+
void cifs_oplock_break(struct work_struct *work)
{
struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
struct inode *inode = cfile->dentry->d_inode;
struct cifsInodeInfo *cinode = CIFS_I(inode);
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
+ struct TCP_Server_Info *server = tcon->ses->server;
int rc = 0;
+ wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS,
+ cifs_pending_writers_wait, TASK_UNINTERRUPTIBLE);
+
+ server->ops->downgrade_oplock(server, cinode,
+ test_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cinode->flags));
+
if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) &&
cifs_has_mand_locks(cinode)) {
cifs_dbg(FYI, "Reset oplock to None for inode=%p due to mand locks\n",
cinode);
cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
}
+ cifs_done_oplock_break(cinode);
}
/*
cifs_dbg(FYI, "file id match, oplock break\n");
pCifsInode = CIFS_I(netfile->dentry->d_inode);
- cifs_set_oplock_level(pCifsInode,
- pSMB->OplockLevel ? OPLOCK_READ : 0);
+ set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK,
+ &pCifsInode->flags);
+
+ /*
+ * Set flag if the server downgrades the oplock
+ * to L2 else clear.
+ */
+ if (pSMB->OplockLevel)
+ set_bit(
+ CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+ &pCifsInode->flags);
+ else
+ clear_bit(
+ CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+ &pCifsInode->flags);
+
queue_work(cifsiod_wq,
&netfile->oplock_break);
netfile->oplock_break_cancelled = false;
cinode->oplock = 0;
}
+static int
+cifs_oplock_break_wait(void *unused)
+{
+ schedule();
+ return signal_pending(current) ? -ERESTARTSYS : 0;
+}
+
+/*
+ * We wait for oplock breaks to be processed before we attempt to perform
+ * writes.
+ */
+int cifs_get_writer(struct cifsInodeInfo *cinode)
+{
+ int rc;
+
+start:
+ rc = wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK,
+ cifs_oplock_break_wait, TASK_KILLABLE);
+ if (rc)
+ return rc;
+
+ spin_lock(&cinode->writers_lock);
+ if (!cinode->writers)
+ set_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags);
+ cinode->writers++;
+ /* Check to see if we have started servicing an oplock break */
+ if (test_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags)) {
+ cinode->writers--;
+ if (cinode->writers == 0) {
+ clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags);
+ wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS);
+ }
+ spin_unlock(&cinode->writers_lock);
+ goto start;
+ }
+ spin_unlock(&cinode->writers_lock);
+ return 0;
+}
+
+void cifs_put_writer(struct cifsInodeInfo *cinode)
+{
+ spin_lock(&cinode->writers_lock);
+ cinode->writers--;
+ if (cinode->writers == 0) {
+ clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags);
+ wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS);
+ }
+ spin_unlock(&cinode->writers_lock);
+}
+
+void cifs_done_oplock_break(struct cifsInodeInfo *cinode)
+{
+ clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags);
+ wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK);
+}
+
bool
backup_cred(struct cifs_sb_info *cifs_sb)
{
return 0;
}
+static void
+cifs_downgrade_oplock(struct TCP_Server_Info *server,
+ struct cifsInodeInfo *cinode, bool set_level2)
+{
+ if (set_level2)
+ cifs_set_oplock_level(cinode, OPLOCK_READ);
+ else
+ cifs_set_oplock_level(cinode, 0);
+}
+
static bool
cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server,
char *buf, int malformed)
.clear_stats = cifs_clear_stats,
.print_stats = cifs_print_stats,
.is_oplock_break = is_valid_oplock_break,
+ .downgrade_oplock = cifs_downgrade_oplock,
.check_trans2 = cifs_check_trans2,
.need_neg = cifs_need_neg,
.negotiate = cifs_negotiate,
else
cfile->oplock_break_cancelled = false;
- server->ops->set_oplock_level(cinode,
- rsp->OplockLevel ? SMB2_OPLOCK_LEVEL_II : 0,
- 0, NULL);
+ set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK,
+ &cinode->flags);
+
+ /*
+ * Set flag if the server downgrades the oplock
+ * to L2 else clear.
+ */
+ if (rsp->OplockLevel)
+ set_bit(
+ CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+ &cinode->flags);
+ else
+ clear_bit(
+ CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+ &cinode->flags);
queue_work(cifsiod_wq, &cfile->oplock_break);
return rc;
}
+static void
+smb2_downgrade_oplock(struct TCP_Server_Info *server,
+ struct cifsInodeInfo *cinode, bool set_level2)
+{
+ if (set_level2)
+ server->ops->set_oplock_level(cinode, SMB2_OPLOCK_LEVEL_II,
+ 0, NULL);
+ else
+ server->ops->set_oplock_level(cinode, 0, 0, NULL);
+}
+
static void
smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
unsigned int epoch, bool *purge_cache)
.clear_stats = smb2_clear_stats,
.print_stats = smb2_print_stats,
.is_oplock_break = smb2_is_valid_oplock_break,
+ .downgrade_oplock = smb2_downgrade_oplock,
.need_neg = smb2_need_neg,
.negotiate = smb2_negotiate,
.negotiate_wsize = smb2_negotiate_wsize,
.clear_stats = smb2_clear_stats,
.print_stats = smb2_print_stats,
.is_oplock_break = smb2_is_valid_oplock_break,
+ .downgrade_oplock = smb2_downgrade_oplock,
.need_neg = smb2_need_neg,
.negotiate = smb2_negotiate,
.negotiate_wsize = smb2_negotiate_wsize,
.print_stats = smb2_print_stats,
.dump_share_caps = smb2_dump_share_caps,
.is_oplock_break = smb2_is_valid_oplock_break,
+ .downgrade_oplock = smb2_downgrade_oplock,
.need_neg = smb2_need_neg,
.negotiate = smb2_negotiate,
.negotiate_wsize = smb2_negotiate_wsize,
u64 persistent_fid, u64 volatile_fid)
{
int rc;
- char *res_key = NULL;
struct compress_ioctl fsctl_input;
char *ret_data = NULL;
2 /* in data len */, &ret_data /* out data */, NULL);
cifs_dbg(FYI, "set compression rc %d\n", rc);
- kfree(res_key);
return rc;
}
case F_GETLK64:
case F_SETLK64:
case F_SETLKW64:
- case F_GETLKP:
- case F_SETLKP:
- case F_SETLKPW:
+ case F_OFD_GETLK:
+ case F_OFD_SETLK:
+ case F_OFD_SETLKW:
ret = get_compat_flock64(&f, compat_ptr(arg));
if (ret != 0)
break;
conv_cmd = convert_fcntl_cmd(cmd);
ret = sys_fcntl(fd, conv_cmd, (unsigned long)&f);
set_fs(old_fs);
- if ((conv_cmd == F_GETLK || conv_cmd == F_GETLKP) && ret == 0) {
+ if ((conv_cmd == F_GETLK || conv_cmd == F_OFD_GETLK) && ret == 0) {
/* need to return lock information - see above for commentary */
if (f.l_start > COMPAT_LOFF_T_MAX)
ret = -EOVERFLOW;
case F_GETLK64:
case F_SETLK64:
case F_SETLKW64:
- case F_GETLKP:
- case F_SETLKP:
- case F_SETLKPW:
+ case F_OFD_GETLK:
+ case F_OFD_SETLK:
+ case F_OFD_SETLKW:
return -EINVAL;
}
return compat_sys_fcntl64(fd, cmd, arg);
static int cn_vprintf(struct core_name *cn, const char *fmt, va_list arg)
{
int free, need;
+ va_list arg_copy;
again:
free = cn->size - cn->used;
- need = vsnprintf(cn->corename + cn->used, free, fmt, arg);
+
+ va_copy(arg_copy, arg);
+ need = vsnprintf(cn->corename + cn->used, free, fmt, arg_copy);
+ va_end(arg_copy);
+
if (need < free) {
cn->used += need;
return 0;
continue;
x = ext4_count_free(bitmap_bh->b_data,
- EXT4_BLOCKS_PER_GROUP(sb) / 8);
+ EXT4_CLUSTERS_PER_GROUP(sb) / 8);
printk(KERN_DEBUG "group %u: stored = %d, counted = %u\n",
i, ext4_free_group_clusters(sb, gdp), x);
bitmap_count += x;
up_write(&EXT4_I(inode)->i_data_sem);
}
-/*
- * Update i_disksize after writeback has been started. Races with truncate
- * are avoided by checking i_size under i_data_sem.
- */
-static inline void ext4_wb_update_i_disksize(struct inode *inode, loff_t newsize)
-{
- loff_t i_size;
-
- down_write(&EXT4_I(inode)->i_data_sem);
- i_size = i_size_read(inode);
- if (newsize > i_size)
- newsize = i_size;
- if (newsize > EXT4_I(inode)->i_disksize)
- EXT4_I(inode)->i_disksize = newsize;
- up_write(&EXT4_I(inode)->i_data_sem);
-}
-
struct ext4_group_info {
unsigned long bb_state;
struct rb_root bb_free_root;
return PTR_ERR(path);
depth = ext_depth(inode);
ex = path[depth].p_ext;
+ if (!ex) {
+ EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
+ (unsigned long) map->m_lblk);
+ return -EIO;
+ }
uninitialized = ext4_ext_is_uninitialized(ex);
split_flag1 = 0;
}
depth = ext_depth(inode);
ex = path[depth].p_ext;
+ if (!ex) {
+ EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
+ (unsigned long) map->m_lblk);
+ err = -EIO;
+ goto out;
+ }
}
err = ext4_ext_get_access(handle, inode, path + depth);
trace_ext4_zero_range(inode, offset, len, mode);
+ if (!S_ISREG(inode->i_mode))
+ return -EINVAL;
+
/*
* Write out all dirty pages to avoid race conditions
* Then release them.
if (mode & FALLOC_FL_PUNCH_HOLE)
return ext4_punch_hole(inode, offset, len);
- if (mode & FALLOC_FL_COLLAPSE_RANGE)
- return ext4_collapse_range(inode, offset, len);
-
ret = ext4_convert_inline_data(inode);
if (ret)
return ret;
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
return -EOPNOTSUPP;
+ if (mode & FALLOC_FL_COLLAPSE_RANGE)
+ return ext4_collapse_range(inode, offset, len);
+
if (mode & FALLOC_FL_ZERO_RANGE)
return ext4_zero_range(file, offset, len, mode);
if (ex_start == EXT_FIRST_EXTENT(path[depth].p_hdr))
update = 1;
- *start = ex_last->ee_block +
+ *start = le32_to_cpu(ex_last->ee_block) +
ext4_ext_get_actual_len(ex_last);
while (ex_start <= ex_last) {
- ex_start->ee_block -= shift;
- if (ex_start >
- EXT_FIRST_EXTENT(path[depth].p_hdr)) {
- if (ext4_ext_try_to_merge_right(inode,
- path, ex_start - 1))
- ex_last--;
- }
- ex_start++;
+ le32_add_cpu(&ex_start->ee_block, -shift);
+ /* Try to merge to the left. */
+ if ((ex_start >
+ EXT_FIRST_EXTENT(path[depth].p_hdr)) &&
+ ext4_ext_try_to_merge_right(inode,
+ path, ex_start - 1))
+ ex_last--;
+ else
+ ex_start++;
}
err = ext4_ext_dirty(handle, inode, path + depth);
if (err)
if (err)
goto out;
- path[depth].p_idx->ei_block -= shift;
+ le32_add_cpu(&path[depth].p_idx->ei_block, -shift);
err = ext4_ext_dirty(handle, inode, path + depth);
if (err)
goto out;
return ret;
}
- stop_block = extent->ee_block + ext4_ext_get_actual_len(extent);
+ stop_block = le32_to_cpu(extent->ee_block) +
+ ext4_ext_get_actual_len(extent);
ext4_ext_drop_refs(path);
kfree(path);
* enough to accomodate the shift.
*/
path = ext4_ext_find_extent(inode, start - 1, NULL, 0);
+ if (IS_ERR(path))
+ return PTR_ERR(path);
depth = path->p_depth;
extent = path[depth].p_ext;
- ex_start = extent->ee_block;
- ex_end = extent->ee_block + ext4_ext_get_actual_len(extent);
+ if (extent) {
+ ex_start = le32_to_cpu(extent->ee_block);
+ ex_end = le32_to_cpu(extent->ee_block) +
+ ext4_ext_get_actual_len(extent);
+ } else {
+ ex_start = 0;
+ ex_end = 0;
+ }
ext4_ext_drop_refs(path);
kfree(path);
return PTR_ERR(path);
depth = path->p_depth;
extent = path[depth].p_ext;
- current_block = extent->ee_block;
+ if (!extent) {
+ EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
+ (unsigned long) start);
+ return -EIO;
+ }
+
+ current_block = le32_to_cpu(extent->ee_block);
if (start > current_block) {
/* Hole, move to the next extent */
ret = mext_next_extent(inode, path, &extent);
ext4_lblk_t punch_start, punch_stop;
handle_t *handle;
unsigned int credits;
- loff_t new_size;
+ loff_t new_size, ioffset;
int ret;
- BUG_ON(offset + len > i_size_read(inode));
-
/* Collapse range works only on fs block size aligned offsets. */
if (offset & (EXT4_BLOCK_SIZE(sb) - 1) ||
len & (EXT4_BLOCK_SIZE(sb) - 1))
return -EINVAL;
if (!S_ISREG(inode->i_mode))
+ return -EINVAL;
+
+ if (EXT4_SB(inode->i_sb)->s_cluster_ratio > 1)
return -EOPNOTSUPP;
trace_ext4_collapse_range(inode, offset, len);
punch_start = offset >> EXT4_BLOCK_SIZE_BITS(sb);
punch_stop = (offset + len) >> EXT4_BLOCK_SIZE_BITS(sb);
+ /* Call ext4_force_commit to flush all data in case of data=journal. */
+ if (ext4_should_journal_data(inode)) {
+ ret = ext4_force_commit(inode->i_sb);
+ if (ret)
+ return ret;
+ }
+
+ /*
+ * Need to round down offset to be aligned with page size boundary
+ * for page size > block size.
+ */
+ ioffset = round_down(offset, PAGE_SIZE);
+
/* Write out all dirty pages */
- ret = filemap_write_and_wait_range(inode->i_mapping, offset, -1);
+ ret = filemap_write_and_wait_range(inode->i_mapping, ioffset,
+ LLONG_MAX);
if (ret)
return ret;
/* Take mutex lock */
mutex_lock(&inode->i_mutex);
- /* It's not possible punch hole on append only file */
- if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
- ret = -EPERM;
- goto out_mutex;
- }
-
- if (IS_SWAPFILE(inode)) {
- ret = -ETXTBSY;
+ /*
+ * There is no need to overlap collapse range with EOF, in which case
+ * it is effectively a truncate operation
+ */
+ if (offset + len >= i_size_read(inode)) {
+ ret = -EINVAL;
goto out_mutex;
}
goto out_mutex;
}
- truncate_pagecache_range(inode, offset, -1);
+ truncate_pagecache(inode, ioffset);
/* Wait for existing dio to complete */
ext4_inode_block_unlocked_dio(inode);
ext4_discard_preallocations(inode);
ret = ext4_es_remove_extent(inode, punch_start,
- EXT_MAX_BLOCKS - punch_start - 1);
+ EXT_MAX_BLOCKS - punch_start);
if (ret) {
up_write(&EXT4_I(inode)->i_data_sem);
goto out_stop;
up_write(&EXT4_I(inode)->i_data_sem);
goto out_stop;
}
+ ext4_discard_preallocations(inode);
ret = ext4_ext_shift_extents(inode, handle, punch_stop,
punch_stop - punch_start);
}
new_size = i_size_read(inode) - len;
- truncate_setsize(inode, new_size);
+ i_size_write(inode, new_size);
EXT4_I(inode)->i_disksize = new_size;
- ext4_discard_preallocations(inode);
up_write(&EXT4_I(inode)->i_data_sem);
if (IS_SYNC(inode))
ext4_handle_sync(handle);
newes.es_lblk = end + 1;
newes.es_len = len2;
- block = 0x7FDEADBEEF;
+ block = 0x7FDEADBEEFULL;
if (ext4_es_is_written(&orig_es) ||
ext4_es_is_unwritten(&orig_es))
block = ext4_es_pblock(&orig_es) +
size_t count = iov_length(iov, nr_segs);
loff_t final_size = pos + count;
- if (pos >= inode->i_size)
+ if (pos >= i_size_read(inode))
return 0;
if ((pos & blockmask) || (final_size & blockmask))
if (unlikely(map->m_len > INT_MAX))
map->m_len = INT_MAX;
+ /* We can handle the block number less than EXT_MAX_BLOCKS */
+ if (unlikely(map->m_lblk >= EXT_MAX_BLOCKS))
+ return -EIO;
+
/* Lookup extent status tree firstly */
if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) {
ext4_es_lru_add(inode);
return err;
} while (map->m_len);
- /* Update on-disk size after IO is submitted */
+ /*
+ * Update on-disk size after IO is submitted. Races with
+ * truncate are avoided by checking i_size under i_data_sem.
+ */
disksize = ((loff_t)mpd->first_page) << PAGE_CACHE_SHIFT;
if (disksize > EXT4_I(inode)->i_disksize) {
int err2;
-
- ext4_wb_update_i_disksize(inode, disksize);
+ loff_t i_size;
+
+ down_write(&EXT4_I(inode)->i_data_sem);
+ i_size = i_size_read(inode);
+ if (disksize > i_size)
+ disksize = i_size;
+ if (disksize > EXT4_I(inode)->i_disksize)
+ EXT4_I(inode)->i_disksize = disksize;
err2 = ext4_mark_inode_dirty(handle, inode);
+ up_write(&EXT4_I(inode)->i_data_sem);
if (err2)
ext4_error(inode->i_sb,
"Failed to mark inode %lu dirty",
}
mutex_lock(&inode->i_mutex);
- /* It's not possible punch hole on append only file */
- if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
- ret = -EPERM;
- goto out_mutex;
- }
- if (IS_SWAPFILE(inode)) {
- ret = -ETXTBSY;
- goto out_mutex;
- }
/* No need to punch hole beyond i_size */
if (offset >= inode->i_size)
ret = ext4_free_hole_blocks(handle, inode, first_block,
stop_block);
- ext4_discard_preallocations(inode);
up_write(&EXT4_I(inode)->i_data_sem);
if (IS_SYNC(inode))
ext4_handle_sync(handle);
*
* We are called from a few places:
*
- * - Within generic_file_write() for O_SYNC files.
+ * - Within generic_file_aio_write() -> generic_write_sync() for O_SYNC files.
* Here, there will be no transaction running. We wait for any running
* transaction to commit.
*
- * - Within sys_sync(), kupdate and such.
- * We wait on commit, if tol to.
+ * - Within flush work (sys_sync(), kupdate and such).
+ * We wait on commit, if told to.
*
- * - Within prune_icache() (PF_MEMALLOC == true)
- * Here we simply return. We can't afford to block kswapd on the
- * journal commit.
+ * - Within iput_final() -> write_inode_now()
+ * We wait on commit, if told to.
*
* In all cases it is actually safe for us to return without doing anything,
* because the inode has been copied into a raw inode buffer in
- * ext4_mark_inode_dirty(). This is a correctness thing for O_SYNC and for
- * knfsd.
+ * ext4_mark_inode_dirty(). This is a correctness thing for WB_SYNC_ALL
+ * writeback.
*
* Note that we are absolutely dependent upon all inode dirtiers doing the
* right thing: they *must* call mark_inode_dirty() after dirtying info in
* stuff();
* inode->i_size = expr;
*
- * is in error because a kswapd-driven write_inode() could occur while
- * `stuff()' is running, and the new i_size will be lost. Plus the inode
- * will no longer be on the superblock's dirty inode list.
+ * is in error because write_inode() could occur while `stuff()' is running,
+ * and the new i_size will be lost. Plus the inode will no longer be on the
+ * superblock's dirty inode list.
*/
int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
{
int err;
- if (current->flags & PF_MEMALLOC)
+ if (WARN_ON_ONCE(current->flags & PF_MEMALLOC))
return 0;
if (EXT4_SB(inode->i_sb)->s_journal) {
poff = block % blocks_per_page;
page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
if (!page)
- return -EIO;
+ return -ENOMEM;
BUG_ON(page->mapping != inode->i_mapping);
e4b->bd_bitmap_page = page;
e4b->bd_bitmap = page_address(page) + (poff * sb->s_blocksize);
pnum = block / blocks_per_page;
page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
if (!page)
- return -EIO;
+ return -ENOMEM;
BUG_ON(page->mapping != inode->i_mapping);
e4b->bd_buddy_page = page;
return 0;
unlock_page(page);
}
}
- if (page == NULL || !PageUptodate(page)) {
+ if (page == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ if (!PageUptodate(page)) {
ret = -EIO;
goto err;
}
unlock_page(page);
}
}
- if (page == NULL || !PageUptodate(page)) {
+ if (page == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ if (!PageUptodate(page)) {
ret = -EIO;
goto err;
}
*/
static int ext4_trim_extent(struct super_block *sb, int start, int count,
ext4_group_t group, struct ext4_buddy *e4b)
+__releases(bitlock)
+__acquires(bitlock)
{
struct ext4_free_extent ex;
int ret = 0;
if (error) {
struct inode *inode = io_end->inode;
- ext4_warning(inode->i_sb, "I/O error writing to inode %lu "
+ ext4_warning(inode->i_sb, "I/O error %d writing to inode %lu "
"(offset %llu size %ld starting block %llu)",
- inode->i_ino,
+ error, inode->i_ino,
(unsigned long long) io_end->offset,
(long) io_end->size,
(unsigned long long)
bi_sector >> (inode->i_blkbits - 9));
+ mapping_set_error(inode->i_mapping, error);
}
if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
goto failed_mount2;
}
}
+
+ /*
+ * set up enough so that it can read an inode,
+ * and create new inode for buddy allocator
+ */
+ sbi->s_gdb_count = db_count;
+ if (!test_opt(sb, NOLOAD) &&
+ EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
+ sb->s_op = &ext4_sops;
+ else
+ sb->s_op = &ext4_nojournal_sops;
+
+ ext4_ext_init(sb);
+ err = ext4_mb_init(sb);
+ if (err) {
+ ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
+ err);
+ goto failed_mount2;
+ }
+
if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
- goto failed_mount2;
+ goto failed_mount2a;
}
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
if (!ext4_fill_flex_info(sb)) {
ext4_msg(sb, KERN_ERR,
"unable to initialize "
"flex_bg meta info!");
- goto failed_mount2;
+ goto failed_mount2a;
}
- sbi->s_gdb_count = db_count;
get_random_bytes(&sbi->s_next_generation, sizeof(u32));
spin_lock_init(&sbi->s_next_gen_lock);
sbi->s_stripe = ext4_get_stripe_size(sbi);
sbi->s_extent_max_zeroout_kb = 32;
- /*
- * set up enough so that it can read an inode
- */
- if (!test_opt(sb, NOLOAD) &&
- EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
- sb->s_op = &ext4_sops;
- else
- sb->s_op = &ext4_nojournal_sops;
sb->s_export_op = &ext4_export_ops;
sb->s_xattr = ext4_xattr_handlers;
#ifdef CONFIG_QUOTA
if (err) {
ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for "
"reserved pool", ext4_calculate_resv_clusters(sb));
- goto failed_mount4a;
+ goto failed_mount5;
}
err = ext4_setup_system_zone(sb);
if (err) {
ext4_msg(sb, KERN_ERR, "failed to initialize system "
"zone (%d)", err);
- goto failed_mount4a;
- }
-
- ext4_ext_init(sb);
- err = ext4_mb_init(sb);
- if (err) {
- ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
- err);
goto failed_mount5;
}
failed_mount7:
ext4_unregister_li_request(sb);
failed_mount6:
- ext4_mb_release(sb);
-failed_mount5:
- ext4_ext_release(sb);
ext4_release_system_zone(sb);
-failed_mount4a:
+failed_mount5:
dput(sb->s_root);
sb->s_root = NULL;
failed_mount4:
percpu_counter_destroy(&sbi->s_extent_cache_cnt);
if (sbi->s_mmp_tsk)
kthread_stop(sbi->s_mmp_tsk);
+failed_mount2a:
+ ext4_mb_release(sb);
failed_mount2:
for (i = 0; i < db_count; i++)
brelse(sbi->s_group_desc[i]);
ext4_kvfree(sbi->s_group_desc);
failed_mount:
+ ext4_ext_release(sb);
if (sbi->s_chksum_driver)
crypto_free_shash(sbi->s_chksum_driver);
if (sbi->s_proc) {
}
/*
- * Release the xattr block BH: If the reference count is > 1, decrement
- * it; otherwise free the block.
+ * Release the xattr block BH: If the reference count is > 1, decrement it;
+ * otherwise free the block.
*/
static void
ext4_xattr_release_block(handle_t *handle, struct inode *inode,
if (ce)
mb_cache_entry_free(ce);
get_bh(bh);
+ unlock_buffer(bh);
ext4_free_blocks(handle, inode, bh, 0, 1,
EXT4_FREE_BLOCKS_METADATA |
EXT4_FREE_BLOCKS_FORGET);
- unlock_buffer(bh);
} else {
le32_add_cpu(&BHDR(bh)->h_refcount, -1);
if (ce)
mb_cache_entry_release(ce);
+ /*
+ * Beware of this ugliness: Releasing of xattr block references
+ * from different inodes can race and so we have to protect
+ * from a race where someone else frees the block (and releases
+ * its journal_head) before we are done dirtying the buffer. In
+ * nojournal mode this race is harmless and we actually cannot
+ * call ext4_handle_dirty_xattr_block() with locked buffer as
+ * that function can call sync_dirty_buffer() so for that case
+ * we handle the dirtying after unlocking the buffer.
+ */
+ if (ext4_handle_valid(handle))
+ error = ext4_handle_dirty_xattr_block(handle, inode,
+ bh);
unlock_buffer(bh);
- error = ext4_handle_dirty_xattr_block(handle, inode, bh);
+ if (!ext4_handle_valid(handle))
+ error = ext4_handle_dirty_xattr_block(handle, inode,
+ bh);
if (IS_SYNC(inode))
ext4_handle_sync(handle);
dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1));
break;
#if BITS_PER_LONG != 32
/* 32-bit arches must use fcntl64() */
- case F_GETLKP:
+ case F_OFD_GETLK:
#endif
case F_GETLK:
err = fcntl_getlk(filp, cmd, (struct flock __user *) arg);
break;
#if BITS_PER_LONG != 32
/* 32-bit arches must use fcntl64() */
- case F_SETLKP:
- case F_SETLKPW:
+ case F_OFD_SETLK:
+ case F_OFD_SETLKW:
#endif
/* Fallthrough */
case F_SETLK:
switch (cmd) {
case F_GETLK64:
- case F_GETLKP:
+ case F_OFD_GETLK:
err = fcntl_getlk64(f.file, cmd, (struct flock64 __user *) arg);
break;
case F_SETLK64:
case F_SETLKW64:
- case F_SETLKP:
- case F_SETLKPW:
+ case F_OFD_SETLK:
+ case F_OFD_SETLKW:
err = fcntl_setlk64(fd, f.file, cmd,
(struct flock64 __user *) arg);
break;
struct rb_node **node = &kn->parent->dir.children.rb_node;
struct rb_node *parent = NULL;
- if (kernfs_type(kn) == KERNFS_DIR)
- kn->parent->dir.subdirs++;
-
while (*node) {
struct kernfs_node *pos;
int result;
else
return -EEXIST;
}
+
/* add new node and rebalance the tree */
rb_link_node(&kn->rb, parent, node);
rb_insert_color(&kn->rb, &kn->parent->dir.children);
+
+ /* successfully added, account subdir number */
+ if (kernfs_type(kn) == KERNFS_DIR)
+ kn->parent->dir.subdirs++;
+
return 0;
}
ops = kernfs_ops(of->kn);
rc = ops->mmap(of, vma);
+ if (rc)
+ goto out_put;
/*
* PowerPC's pci_mmap of legacy_mem uses shmem_zero_setup()
static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
{
+ static DEFINE_MUTEX(iattr_mutex);
+ struct kernfs_iattrs *ret;
struct iattr *iattrs;
+ mutex_lock(&iattr_mutex);
+
if (kn->iattr)
- return kn->iattr;
+ goto out_unlock;
kn->iattr = kzalloc(sizeof(struct kernfs_iattrs), GFP_KERNEL);
if (!kn->iattr)
- return NULL;
+ goto out_unlock;
iattrs = &kn->iattr->ia_iattr;
/* assign default attributes */
iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME;
simple_xattrs_init(&kn->iattr->xattrs);
-
- return kn->iattr;
+out_unlock:
+ ret = kn->iattr;
+ mutex_unlock(&iattr_mutex);
+ return ret;
}
static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr)
#define IS_POSIX(fl) (fl->fl_flags & FL_POSIX)
#define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK)
#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG))
-#define IS_FILE_PVT(fl) (fl->fl_flags & FL_FILE_PVT)
+#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK)
static bool lease_breaking(struct file_lock *fl)
{
BUG_ON(!list_empty(&waiter->fl_block));
waiter->fl_next = blocker;
list_add_tail(&waiter->fl_block, &blocker->fl_block);
- if (IS_POSIX(blocker) && !IS_FILE_PVT(blocker))
+ if (IS_POSIX(blocker) && !IS_OFDLCK(blocker))
locks_insert_global_blocked(waiter);
}
* of tasks (such as posix threads) sharing the same open file table.
* To handle those cases, we just bail out after a few iterations.
*
- * For FL_FILE_PVT locks, the owner is the filp, not the files_struct.
+ * For FL_OFDLCK locks, the owner is the filp, not the files_struct.
* Because the owner is not even nominally tied to a thread of
* execution, the deadlock detection below can't reasonably work well. Just
* skip it for those.
*
- * In principle, we could do a more limited deadlock detection on FL_FILE_PVT
+ * In principle, we could do a more limited deadlock detection on FL_OFDLCK
* locks that just checks for the case where two tasks are attempting to
* upgrade from read to write locks on the same inode.
*/
/*
* This deadlock detector can't reasonably detect deadlocks with
- * FL_FILE_PVT locks, since they aren't owned by a process, per-se.
+ * FL_OFDLCK locks, since they aren't owned by a process, per-se.
*/
- if (IS_FILE_PVT(caller_fl))
+ if (IS_OFDLCK(caller_fl))
return 0;
while ((block_fl = what_owner_is_waiting_for(block_fl))) {
restart:
break_time = flock->fl_break_time;
- if (break_time != 0) {
+ if (break_time != 0)
break_time -= jiffies;
- if (break_time == 0)
- break_time++;
- }
+ if (break_time == 0)
+ break_time++;
locks_insert_block(flock, new_fl);
spin_unlock(&inode->i_lock);
error = wait_event_interruptible_timeout(new_fl->fl_wait,
static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
{
- flock->l_pid = IS_FILE_PVT(fl) ? -1 : fl->fl_pid;
+ flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid;
#if BITS_PER_LONG == 32
/*
* Make sure we can represent the posix lock via
#if BITS_PER_LONG == 32
static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
{
- flock->l_pid = IS_FILE_PVT(fl) ? -1 : fl->fl_pid;
+ flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid;
flock->l_start = fl->fl_start;
flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
fl->fl_end - fl->fl_start + 1;
if (error)
goto out;
- if (cmd == F_GETLKP) {
+ if (cmd == F_OFD_GETLK) {
error = -EINVAL;
if (flock.l_pid != 0)
goto out;
cmd = F_GETLK;
- file_lock.fl_flags |= FL_FILE_PVT;
+ file_lock.fl_flags |= FL_OFDLCK;
file_lock.fl_owner = (fl_owner_t)filp;
}
/*
* If the cmd is requesting file-private locks, then set the
- * FL_FILE_PVT flag and override the owner.
+ * FL_OFDLCK flag and override the owner.
*/
switch (cmd) {
- case F_SETLKP:
+ case F_OFD_SETLK:
error = -EINVAL;
if (flock.l_pid != 0)
goto out;
cmd = F_SETLK;
- file_lock->fl_flags |= FL_FILE_PVT;
+ file_lock->fl_flags |= FL_OFDLCK;
file_lock->fl_owner = (fl_owner_t)filp;
break;
- case F_SETLKPW:
+ case F_OFD_SETLKW:
error = -EINVAL;
if (flock.l_pid != 0)
goto out;
cmd = F_SETLKW;
- file_lock->fl_flags |= FL_FILE_PVT;
+ file_lock->fl_flags |= FL_OFDLCK;
file_lock->fl_owner = (fl_owner_t)filp;
/* Fallthrough */
case F_SETLKW:
if (error)
goto out;
- if (cmd == F_GETLKP) {
+ if (cmd == F_OFD_GETLK) {
error = -EINVAL;
if (flock.l_pid != 0)
goto out;
cmd = F_GETLK64;
- file_lock.fl_flags |= FL_FILE_PVT;
+ file_lock.fl_flags |= FL_OFDLCK;
file_lock.fl_owner = (fl_owner_t)filp;
}
/*
* If the cmd is requesting file-private locks, then set the
- * FL_FILE_PVT flag and override the owner.
+ * FL_OFDLCK flag and override the owner.
*/
switch (cmd) {
- case F_SETLKP:
+ case F_OFD_SETLK:
error = -EINVAL;
if (flock.l_pid != 0)
goto out;
cmd = F_SETLK64;
- file_lock->fl_flags |= FL_FILE_PVT;
+ file_lock->fl_flags |= FL_OFDLCK;
file_lock->fl_owner = (fl_owner_t)filp;
break;
- case F_SETLKPW:
+ case F_OFD_SETLKW:
error = -EINVAL;
if (flock.l_pid != 0)
goto out;
cmd = F_SETLKW64;
- file_lock->fl_flags |= FL_FILE_PVT;
+ file_lock->fl_flags |= FL_OFDLCK;
file_lock->fl_owner = (fl_owner_t)filp;
/* Fallthrough */
case F_SETLKW64:
if (IS_POSIX(fl)) {
if (fl->fl_flags & FL_ACCESS)
seq_printf(f, "ACCESS");
- else if (IS_FILE_PVT(fl))
- seq_printf(f, "FLPVT ");
+ else if (IS_OFDLCK(fl))
+ seq_printf(f, "OFDLCK");
else
seq_printf(f, "POSIX ");
static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
{
+ int maxtime = max_cb_time(clp->net);
struct rpc_timeout timeparms = {
- .to_initval = max_cb_time(clp->net),
+ .to_initval = maxtime,
.to_retries = 0,
+ .to_maxval = maxtime,
};
struct rpc_create_args args = {
.net = clp->net,
/* nfsd4_check_resp_size guarantees enough room for error status */
if (!op->status)
op->status = nfsd4_check_resp_size(resp, 0);
- if (op->status == nfserr_resource && nfsd4_has_session(&resp->cstate)) {
- struct nfsd4_slot *slot = resp->cstate.slot;
-
- if (slot->sl_flags & NFSD4_SLOT_CACHETHIS)
- op->status = nfserr_rep_too_big_to_cache;
- else
- op->status = nfserr_rep_too_big;
- }
if (so) {
so->so_replay.rp_status = op->status;
so->so_replay.rp_buflen = (char *)resp->p - (char *)(statp+1);
return -EBADF;
/*
- * It's not possible to punch hole or perform collapse range
- * on append only file
+ * We can only allow pure fallocate on append only files
*/
- if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE)
- && IS_APPEND(inode))
+ if ((mode & ~FALLOC_FL_KEEP_SIZE) && IS_APPEND(inode))
return -EPERM;
if (IS_IMMUTABLE(inode))
return -EPERM;
+ /*
+ * We can not allow to do any fallocate operation on an active
+ * swapfile
+ */
+ if (IS_SWAPFILE(inode))
+ ret = -ETXTBSY;
+
/*
* Revalidate the write permissions, in case security policy has
* changed since the files were opened.
if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
return -EFBIG;
- /*
- * There is no need to overlap collapse range with EOF, in which case
- * it is effectively a truncate operation
- */
- if ((mode & FALLOC_FL_COLLAPSE_RANGE) &&
- (offset + len >= i_size_read(inode)))
- return -EINVAL;
-
if (!file->f_op->fallocate)
return -EOPNOTSUPP;
static DEFINE_IDA(unnamed_dev_ida);
static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */
-static int unnamed_dev_start = 0; /* don't bother trying below it */
+/* Many userspace utilities consider an FSID of 0 invalid.
+ * Always return at least 1 from get_anon_bdev.
+ */
+static int unnamed_dev_start = 1;
int get_anon_bdev(dev_t *p)
{
kernfs_remove_by_name(kobj->sd, attr->attr.name);
}
EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);
-
-struct sysfs_schedule_callback_struct {
- struct list_head workq_list;
- struct kobject *kobj;
- void (*func)(void *);
- void *data;
- struct module *owner;
- struct work_struct work;
-};
-
-static struct workqueue_struct *sysfs_workqueue;
-static DEFINE_MUTEX(sysfs_workq_mutex);
-static LIST_HEAD(sysfs_workq);
-static void sysfs_schedule_callback_work(struct work_struct *work)
-{
- struct sysfs_schedule_callback_struct *ss = container_of(work,
- struct sysfs_schedule_callback_struct, work);
-
- (ss->func)(ss->data);
- kobject_put(ss->kobj);
- module_put(ss->owner);
- mutex_lock(&sysfs_workq_mutex);
- list_del(&ss->workq_list);
- mutex_unlock(&sysfs_workq_mutex);
- kfree(ss);
-}
-
-/**
- * sysfs_schedule_callback - helper to schedule a callback for a kobject
- * @kobj: object we're acting for.
- * @func: callback function to invoke later.
- * @data: argument to pass to @func.
- * @owner: module owning the callback code
- *
- * sysfs attribute methods must not unregister themselves or their parent
- * kobject (which would amount to the same thing). Attempts to do so will
- * deadlock, since unregistration is mutually exclusive with driver
- * callbacks.
- *
- * Instead methods can call this routine, which will attempt to allocate
- * and schedule a workqueue request to call back @func with @data as its
- * argument in the workqueue's process context. @kobj will be pinned
- * until @func returns.
- *
- * Returns 0 if the request was submitted, -ENOMEM if storage could not
- * be allocated, -ENODEV if a reference to @owner isn't available,
- * -EAGAIN if a callback has already been scheduled for @kobj.
- */
-int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
- void *data, struct module *owner)
-{
- struct sysfs_schedule_callback_struct *ss, *tmp;
-
- if (!try_module_get(owner))
- return -ENODEV;
-
- mutex_lock(&sysfs_workq_mutex);
- list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list)
- if (ss->kobj == kobj) {
- module_put(owner);
- mutex_unlock(&sysfs_workq_mutex);
- return -EAGAIN;
- }
- mutex_unlock(&sysfs_workq_mutex);
-
- if (sysfs_workqueue == NULL) {
- sysfs_workqueue = create_singlethread_workqueue("sysfsd");
- if (sysfs_workqueue == NULL) {
- module_put(owner);
- return -ENOMEM;
- }
- }
-
- ss = kmalloc(sizeof(*ss), GFP_KERNEL);
- if (!ss) {
- module_put(owner);
- return -ENOMEM;
- }
- kobject_get(kobj);
- ss->kobj = kobj;
- ss->func = func;
- ss->data = data;
- ss->owner = owner;
- INIT_WORK(&ss->work, sysfs_schedule_callback_work);
- INIT_LIST_HEAD(&ss->workq_list);
- mutex_lock(&sysfs_workq_mutex);
- list_add_tail(&ss->workq_list, &sysfs_workq);
- mutex_unlock(&sysfs_workq_mutex);
- queue_work(sysfs_workqueue, &ss->work);
- return 0;
-}
-EXPORT_SYMBOL_GPL(sysfs_schedule_callback);
/*
* If this is O_DIRECT or the mpage code calling tell them how large
* the mapping is, so that we can avoid repeated get_blocks calls.
+ *
+ * If the mapping spans EOF, then we have to break the mapping up as the
+ * mapping for blocks beyond EOF must be marked new so that sub block
+ * regions can be correctly zeroed. We can't do this for mappings within
+ * EOF unless the mapping was just allocated or is unwritten, otherwise
+ * the callers would overwrite existing data with zeros. Hence we have
+ * to split the mapping into a range up to and including EOF, and a
+ * second mapping for beyond EOF.
*/
if (direct || size > (1 << inode->i_blkbits)) {
xfs_off_t mapping_size;
ASSERT(mapping_size > 0);
if (mapping_size > size)
mapping_size = size;
+ if (offset < i_size_read(inode) &&
+ offset + mapping_size >= i_size_read(inode)) {
+ /* limit mapping to block that spans EOF */
+ mapping_size = roundup_64(i_size_read(inode) - offset,
+ 1 << inode->i_blkbits);
+ }
if (mapping_size > LONG_MAX)
mapping_size = LONG_MAX;
xfs_vm_kill_delalloc_range(inode, block_offset,
block_offset + bh->b_size);
+
+ /*
+ * This buffer does not contain data anymore. make sure anyone
+ * who finds it knows that for certain.
+ */
+ clear_buffer_delay(bh);
+ clear_buffer_uptodate(bh);
+ clear_buffer_mapped(bh);
+ clear_buffer_new(bh);
+ clear_buffer_dirty(bh);
}
}
status = __block_write_begin(page, pos, len, xfs_get_blocks);
if (unlikely(status)) {
struct inode *inode = mapping->host;
+ size_t isize = i_size_read(inode);
xfs_vm_write_failed(inode, page, pos, len);
unlock_page(page);
- if (pos + len > i_size_read(inode))
- truncate_pagecache(inode, i_size_read(inode));
+ /*
+ * If the write is beyond EOF, we only want to kill blocks
+ * allocated in this write, not blocks that were previously
+ * written successfully.
+ */
+ if (pos + len > isize) {
+ ssize_t start = max_t(ssize_t, pos, isize);
+
+ truncate_pagecache_range(inode, start, pos + len);
+ }
page_cache_release(page);
page = NULL;
}
/*
- * On failure, we only need to kill delalloc blocks beyond EOF because they
- * will never be written. For blocks within EOF, generic_write_end() zeros them
- * so they are safe to leave alone and be written with all the other valid data.
+ * On failure, we only need to kill delalloc blocks beyond EOF in the range of
+ * this specific write because they will never be written. Previous writes
+ * beyond EOF where block allocation succeeded do not need to be trashed, so
+ * only new blocks from this write should be trashed. For blocks within
+ * EOF, generic_write_end() zeros them so they are safe to leave alone and be
+ * written with all the other valid data.
*/
STATIC int
xfs_vm_write_end(
loff_t to = pos + len;
if (to > isize) {
- truncate_pagecache(inode, isize);
+ /* only kill blocks in this write beyond EOF */
+ if (pos > isize)
+ isize = pos;
xfs_vm_kill_delalloc_range(inode, isize, to);
+ truncate_pagecache_range(inode, isize, to);
}
}
return ret;
int whichfork = XFS_DATA_FORK;
int logflags;
xfs_filblks_t blockcount = 0;
+ int total_extents;
if (unlikely(XFS_TEST_ERROR(
(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
ASSERT(current_ext != NULL);
ifp = XFS_IFORK_PTR(ip, whichfork);
-
if (!(ifp->if_flags & XFS_IFEXTENTS)) {
/* Read in all the extents */
error = xfs_iread_extents(tp, ip, whichfork);
/* We are going to change core inode */
logflags = XFS_ILOG_CORE;
-
if (ifp->if_flags & XFS_IFBROOT) {
cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
cur->bc_private.b.firstblock = *firstblock;
logflags |= XFS_ILOG_DEXT;
}
- while (nexts++ < num_exts &&
- *current_ext < XFS_IFORK_NEXTENTS(ip, whichfork)) {
+ /*
+ * There may be delalloc extents in the data fork before the range we
+ * are collapsing out, so we cannot
+ * use the count of real extents here. Instead we have to calculate it
+ * from the incore fork.
+ */
+ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
+ while (nexts++ < num_exts && *current_ext < total_extents) {
gotp = xfs_iext_get_ext(ifp, *current_ext);
xfs_bmbt_get_all(gotp, &got);
}
(*current_ext)++;
+ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
}
/* Check if we are done */
- if (*current_ext == XFS_IFORK_NEXTENTS(ip, whichfork))
+ if (*current_ext == total_extents)
*done = 1;
del_cursor:
error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
xfs_trans_log_inode(tp, ip, logflags);
-
return error;
}
xfs_off_t end_boundary;
int error;
+ trace_xfs_zero_file_space(ip);
+
granularity = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
/*
ASSERT(end_boundary <= offset + len);
if (start_boundary < end_boundary - 1) {
- /* punch out the page cache over the conversion range */
+ /*
+ * punch out delayed allocation blocks and the page cache over
+ * the conversion range
+ */
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ error = xfs_bmap_punch_delalloc_range(ip,
+ XFS_B_TO_FSBT(mp, start_boundary),
+ XFS_B_TO_FSB(mp, end_boundary - start_boundary));
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
truncate_pagecache_range(VFS_I(ip), start_boundary,
end_boundary - 1);
+
/* convert the blocks */
error = xfs_alloc_file_space(ip, start_boundary,
end_boundary - start_boundary - 1,
xfs_buf_wait_unpin(bp);
xfs_buf_hold(bp);
- /* Set the count to 1 initially, this will stop an I/O
+ /*
+ * Set the count to 1 initially, this will stop an I/O
* completion callout which happens before we have started
* all the I/O from calling xfs_buf_ioend too early.
*/
atomic_set(&bp->b_io_remaining, 1);
_xfs_buf_ioapply(bp);
- _xfs_buf_ioend(bp, 1);
+ /*
+ * If _xfs_buf_ioapply failed, we'll get back here with
+ * only the reference we took above. _xfs_buf_ioend will
+ * drop it to zero, so we'd better not queue it for later,
+ * or we'll free it before it's done.
+ */
+ _xfs_buf_ioend(bp, bp->b_error ? 0 : 1);
xfs_buf_rele(bp);
}
/*
* Waits for I/O to complete on the buffer supplied. It returns immediately if
- * no I/O is pending or there is already a pending error on the buffer. It
- * returns the I/O error code, if any, or 0 if there was no error.
+ * no I/O is pending or there is already a pending error on the buffer, in which
+ * case nothing will ever complete. It returns the I/O error code, if any, or
+ * 0 if there was no error.
*/
int
xfs_buf_iowait(
goto out;
if (mapping->nrpages) {
- ret = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
+ ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
pos, -1);
if (ret)
goto out;
goto out_unlock;
}
- ASSERT(offset + len < i_size_read(inode));
+ /*
+ * There is no need to overlap collapse range with EOF,
+ * in which case it is effectively a truncate operation
+ */
+ if (offset + len >= i_size_read(inode)) {
+ error = -EINVAL;
+ goto out_unlock;
+ }
+
new_size = i_size_read(inode) - len;
error = xfs_collapse_file_space(ip, offset, len);
xfs_create_tmpfile(
struct xfs_inode *dp,
struct dentry *dentry,
- umode_t mode)
+ umode_t mode,
+ struct xfs_inode **ipp)
{
struct xfs_mount *mp = dp->i_mount;
struct xfs_inode *ip = NULL;
xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
ip->i_d.di_nlink--;
- d_tmpfile(dentry, VFS_I(ip));
error = xfs_iunlink(tp, ip);
if (error)
goto out_trans_abort;
xfs_qm_dqrele(gdqp);
xfs_qm_dqrele(pdqp);
+ *ipp = ip;
return 0;
out_trans_abort:
int xfs_create(struct xfs_inode *dp, struct xfs_name *name,
umode_t mode, xfs_dev_t rdev, struct xfs_inode **ipp);
int xfs_create_tmpfile(struct xfs_inode *dp, struct dentry *dentry,
- umode_t mode);
+ umode_t mode, struct xfs_inode **ipp);
int xfs_remove(struct xfs_inode *dp, struct xfs_name *name,
struct xfs_inode *ip);
int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip,
struct dentry *dentry,
umode_t mode)
{
- int error;
+ int error;
+ struct xfs_inode *ip;
+ struct inode *inode;
- error = xfs_create_tmpfile(XFS_I(dir), dentry, mode);
+ error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip);
+ if (unlikely(error))
+ return -error;
- return -error;
+ inode = VFS_I(ip);
+
+ error = xfs_init_security(inode, dir, &dentry->d_name);
+ if (unlikely(error)) {
+ iput(inode);
+ return -error;
+ }
+
+ d_tmpfile(dentry, inode);
+
+ return 0;
}
static const struct inode_operations xfs_inode_operations = {
/* log I/O is always issued ASYNC */
ASSERT(XFS_BUF_ISASYNC(bp));
xlog_state_done_syncing(iclog, aborted);
+
/*
- * do not reference the buffer (bp) here as we could race
- * with it being freed after writing the unmount record to the
- * log.
+ * drop the buffer lock now that we are done. Nothing references
+ * the buffer after this, so an unmount waiting on this lock can now
+ * tear it down safely. As such, it is unsafe to reference the buffer
+ * (bp) after the unlock as we could race with it being freed.
*/
+ xfs_buf_unlock(bp);
}
/*
bp = xfs_buf_alloc(mp->m_logdev_targp, 0, BTOBB(log->l_iclog_size), 0);
if (!bp)
goto out_free_log;
- bp->b_iodone = xlog_iodone;
+
+ /*
+ * The iclogbuf buffer locks are held over IO but we are not going to do
+ * IO yet. Hence unlock the buffer so that the log IO path can grab it
+ * when appropriately.
+ */
ASSERT(xfs_buf_islocked(bp));
+ xfs_buf_unlock(bp);
+
+ bp->b_iodone = xlog_iodone;
log->l_xbuf = bp;
spin_lock_init(&log->l_icloglock);
if (!bp)
goto out_free_iclog;
+ ASSERT(xfs_buf_islocked(bp));
+ xfs_buf_unlock(bp);
+
bp->b_iodone = xlog_iodone;
iclog->ic_bp = bp;
iclog->ic_data = bp->b_addr;
iclog->ic_callback_tail = &(iclog->ic_callback);
iclog->ic_datap = (char *)iclog->ic_data + log->l_iclog_hsize;
- ASSERT(xfs_buf_islocked(iclog->ic_bp));
init_waitqueue_head(&iclog->ic_force_wait);
init_waitqueue_head(&iclog->ic_write_wait);
* we transition the iclogs to IOERROR state *after* flushing all existing
* iclogs to disk. This is because we don't want anymore new transactions to be
* started or completed afterwards.
+ *
+ * We lock the iclogbufs here so that we can serialise against IO completion
+ * during unmount. We might be processing a shutdown triggered during unmount,
+ * and that can occur asynchronously to the unmount thread, and hence we need to
+ * ensure that completes before tearing down the iclogbufs. Hence we need to
+ * hold the buffer lock across the log IO to acheive that.
*/
STATIC int
xlog_bdstrat(
{
struct xlog_in_core *iclog = bp->b_fspriv;
+ xfs_buf_lock(bp);
if (iclog->ic_state & XLOG_STATE_IOERROR) {
xfs_buf_ioerror(bp, EIO);
xfs_buf_stale(bp);
/*
* It would seem logical to return EIO here, but we rely on
* the log state machine to propagate I/O errors instead of
- * doing it here.
+ * doing it here. Similarly, IO completion will unlock the
+ * buffer, so we don't do it here.
*/
return 0;
}
xlog_cil_destroy(log);
/*
- * always need to ensure that the extra buffer does not point to memory
- * owned by another log buffer before we free it.
+ * Cycle all the iclogbuf locks to make sure all log IO completion
+ * is done before we tear down these buffers.
*/
+ iclog = log->l_iclog;
+ for (i = 0; i < log->l_iclog_bufs; i++) {
+ xfs_buf_lock(iclog->ic_bp);
+ xfs_buf_unlock(iclog->ic_bp);
+ iclog = iclog->ic_next;
+ }
+
+ /*
+ * Always need to ensure that the extra buffer does not point to memory
+ * owned by another log buffer before we free it. Also, cycle the lock
+ * first to ensure we've completed IO on it.
+ */
+ xfs_buf_lock(log->l_xbuf);
+ xfs_buf_unlock(log->l_xbuf);
xfs_buf_set_empty(log->l_xbuf, BTOBB(log->l_iclog_size));
xfs_buf_free(log->l_xbuf);
iclog = log->l_iclog;
- for (i=0; i<log->l_iclog_bufs; i++) {
+ for (i = 0; i < log->l_iclog_bufs; i++) {
xfs_buf_free(iclog->ic_bp);
next_iclog = iclog->ic_next;
kmem_free(iclog);
DEFINE_INODE_EVENT(xfs_inactive_symlink);
DEFINE_INODE_EVENT(xfs_alloc_file_space);
DEFINE_INODE_EVENT(xfs_free_file_space);
+DEFINE_INODE_EVENT(xfs_zero_file_space);
DEFINE_INODE_EVENT(xfs_collapse_file_space);
DEFINE_INODE_EVENT(xfs_readdir);
#ifdef CONFIG_XFS_POSIX_ACL
#ifndef pte_mknonnuma
static inline pte_t pte_mknonnuma(pte_t pte)
{
- pte = pte_clear_flags(pte, _PAGE_NUMA);
- return pte_set_flags(pte, _PAGE_PRESENT|_PAGE_ACCESSED);
+ pteval_t val = pte_val(pte);
+
+ val &= ~_PAGE_NUMA;
+ val |= (_PAGE_PRESENT|_PAGE_ACCESSED);
+ return __pte(val);
}
#endif
#ifndef pmd_mknonnuma
static inline pmd_t pmd_mknonnuma(pmd_t pmd)
{
- pmd = pmd_clear_flags(pmd, _PAGE_NUMA);
- return pmd_set_flags(pmd, _PAGE_PRESENT|_PAGE_ACCESSED);
+ pmdval_t val = pmd_val(pmd);
+
+ val &= ~_PAGE_NUMA;
+ val |= (_PAGE_PRESENT|_PAGE_ACCESSED);
+
+ return __pmd(val);
}
#endif
#ifndef pte_mknuma
static inline pte_t pte_mknuma(pte_t pte)
{
- pte = pte_set_flags(pte, _PAGE_NUMA);
- return pte_clear_flags(pte, _PAGE_PRESENT);
+ pteval_t val = pte_val(pte);
+
+ val &= ~_PAGE_PRESENT;
+ val |= _PAGE_NUMA;
+
+ return __pte(val);
}
#endif
#ifndef pmd_mknuma
static inline pmd_t pmd_mknuma(pmd_t pmd)
{
- pmd = pmd_set_flags(pmd, _PAGE_NUMA);
- return pmd_clear_flags(pmd, _PAGE_PRESENT);
+ pmdval_t val = pmd_val(pmd);
+
+ val &= ~_PAGE_PRESENT;
+ val |= _PAGE_NUMA;
+
+ return __pmd(val);
}
#endif
}
#ifndef zero_bytemask
-#ifdef CONFIG_64BIT
-#define zero_bytemask(mask) (~0ul << fls64(mask))
-#else
-#define zero_bytemask(mask) (~0ul << fls(mask))
-#endif /* CONFIG_64BIT */
-#endif /* zero_bytemask */
+#define zero_bytemask(mask) (~0ul << __fls(mask) << 1)
+#endif
#endif /* _ASM_WORD_AT_A_TIME_H */
struct drm_encoder *(*best_encoder)(struct drm_connector *connector);
};
-extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY);
extern void drm_helper_disable_unused_functions(struct drm_device *dev);
extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
}
extern void drm_helper_resume_force_mode(struct drm_device *dev);
+
+/* drm_probe_helper.c */
+extern int drm_helper_probe_single_connector_modes(struct drm_connector
+ *connector, uint32_t maxX,
+ uint32_t maxY);
extern void drm_kms_helper_poll_init(struct drm_device *dev);
extern void drm_kms_helper_poll_fini(struct drm_device *dev);
extern bool drm_helper_hpd_irq_event(struct drm_device *dev);
* transactions. The drm_dp_aux_register_i2c_bus() function registers an
* I2C adapter that can be passed to drm_probe_ddc(). Upon removal, drivers
* should call drm_dp_aux_unregister_i2c_bus() to remove the I2C adapter.
+ *
+ * Note that the aux helper code assumes that the .transfer() function
+ * only modifies the reply field of the drm_dp_aux_msg structure. The
+ * retry logic and i2c helpers assume this is the case.
*/
struct drm_dp_aux {
const char *name;
/* 10 (register bit affects spdif_in and spdif_out) */
#define TEGRA124_CLK_I2S1 11
#define TEGRA124_CLK_I2C1 12
-#define TEGRA124_CLK_NDFLASH 13
+/* 13 */
#define TEGRA124_CLK_SDMMC1 14
#define TEGRA124_CLK_SDMMC4 15
/* 16 */
/* 64 */
#define TEGRA124_CLK_UARTD 65
-#define TEGRA124_CLK_UARTE 66
+/* 66 */
#define TEGRA124_CLK_I2C3 67
#define TEGRA124_CLK_SBC4 68
#define TEGRA124_CLK_SDMMC3 69
#define TEGRA124_CLK_TRACE 77
#define TEGRA124_CLK_SOC_THERM 78
#define TEGRA124_CLK_DTV 79
-#define TEGRA124_CLK_NDSPEED 80
+/* 80 */
#define TEGRA124_CLK_I2CSLOW 81
#define TEGRA124_CLK_DSIB 82
#define TEGRA124_CLK_TSEC 83
const struct bin_attribute *attr);
extern void device_remove_bin_file(struct device *dev,
const struct bin_attribute *attr);
-extern int device_schedule_callback_owner(struct device *dev,
- void (*func)(struct device *dev), struct module *owner);
-
-/* This is a macro to avoid include problems with THIS_MODULE */
-#define device_schedule_callback(dev, func) \
- device_schedule_callback_owner(dev, func, THIS_MODULE)
/* device resource management */
typedef void (*dr_release_t)(struct device *dev, void *res);
}
extern void devm_kfree(struct device *dev, void *p);
extern char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp);
+extern void *devm_kmemdup(struct device *dev, const void *src, size_t len,
+ gfp_t gfp);
void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
void __iomem *devm_request_and_ioremap(struct device *dev,
extern struct device *__root_device_register(const char *name,
struct module *owner);
-/*
- * This is a macro to avoid include problems with THIS_MODULE,
- * just as per what is done for device_schedule_callback() above.
- */
+/* This is a macro to avoid include problems with THIS_MODULE */
#define root_device_register(name) \
__root_device_register(name, THIS_MODULE)
BPF_S_ANC_RXHASH,
BPF_S_ANC_CPU,
BPF_S_ANC_ALU_XOR_X,
- BPF_S_ANC_SECCOMP_LD_W,
BPF_S_ANC_VLAN_TAG,
BPF_S_ANC_VLAN_TAG_PRESENT,
BPF_S_ANC_PAY_OFFSET,
#define FL_SLEEP 128 /* A blocking lock */
#define FL_DOWNGRADE_PENDING 256 /* Lease is being downgraded */
#define FL_UNLOCK_PENDING 512 /* Lease is being broken */
-#define FL_FILE_PVT 1024 /* lock is private to the file */
+#define FL_OFDLCK 1024 /* lock is "owned" by struct file */
/*
* Special return value from posix_lock_file() and vfs_lock_file() for
--- /dev/null
+#ifndef __LINUX_GOLDFISH_H
+#define __LINUX_GOLDFISH_H
+
+/* Helpers for Goldfish virtual platform */
+
+static inline void gf_write64(unsigned long data,
+ void __iomem *portl, void __iomem *porth)
+{
+ writel((u32)data, portl);
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ writel(data>>32, porth);
+#endif
+}
+
+#endif /* __LINUX_GOLDFISH_H */
struct hid_sensor_hub_device *hsdev;
struct platform_device *pdev;
unsigned usage_id;
- bool data_ready;
+ atomic_t data_ready;
struct iio_trigger *trigger;
struct hid_sensor_hub_attribute_info poll;
struct hid_sensor_hub_attribute_info report_state;
int hid_sensor_get_usage_index(struct hid_sensor_hub_device *hsdev,
u32 report_id, int field_index, u32 usage_id);
+int hid_sensor_format_scale(u32 usage_id,
+ struct hid_sensor_hub_attribute_info *attr_info,
+ int *val0, int *val1);
+
+s32 hid_sensor_read_poll_value(struct hid_sensor_common *st);
+
#endif
#define HID_USAGE_SENSOR_ORIENT_TILT_Y 0x200480
#define HID_USAGE_SENSOR_ORIENT_TILT_Z 0x200481
+#define HID_USAGE_SENSOR_DEVICE_ORIENTATION 0x20008A
#define HID_USAGE_SENSOR_ORIENT_ROTATION_MATRIX 0x200482
#define HID_USAGE_SENSOR_ORIENT_QUATERNION 0x200483
#define HID_USAGE_SENSOR_ORIENT_MAGN_FLUX 0x200484
* 0 . 13 (Windows Server 2008)
* 1 . 1 (Windows 7)
* 2 . 4 (Windows 8)
+ * 3 . 0 (Windows 8 R2)
*/
#define VERSION_WS2008 ((0 << 16) | (13))
#define VERSION_WIN7 ((1 << 16) | (1))
#define VERSION_WIN8 ((2 << 16) | (4))
+#define VERSION_WIN8_1 ((3 << 16) | (0))
#define VERSION_INVAL -1
-#define VERSION_CURRENT VERSION_WIN8
+#define VERSION_CURRENT VERSION_WIN8_1
/* Make maximum size of pipe payload of 16K */
#define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384)
int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable);
+void st_sensors_power_enable(struct iio_dev *indio_dev);
+
+void st_sensors_power_disable(struct iio_dev *indio_dev);
+
int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr);
int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable);
int iio_read_channel_raw(struct iio_channel *chan,
int *val);
+/**
+ * iio_read_channel_average_raw() - read from a given channel
+ * @chan: The channel being queried.
+ * @val: Value read back.
+ *
+ * Note raw reads from iio channels are in adc counts and hence
+ * scale will need to be applied if standard units required.
+ *
+ * In opposit to the normal iio_read_channel_raw this function
+ * returns the average of multiple reads.
+ */
+int iio_read_channel_average_raw(struct iio_channel *chan, int *val);
+
/**
* iio_read_channel_processed() - read processed value from a given channel
* @chan: The channel being queried.
* shift: Shift right by this before masking out
* realbits.
* endianness: little or big endian
+ * repeat: Number of times real/storage bits
+ * repeats. When the repeat element is
+ * more than 1, then the type element in
+ * sysfs will show a repeat value.
+ * Otherwise, the number of repetitions is
+ * omitted.
* @info_mask_separate: What information is to be exported that is specific to
* this channel.
* @info_mask_shared_by_type: What information is to be exported that is shared
u8 realbits;
u8 storagebits;
u8 shift;
+ u8 repeat;
enum iio_endian endianness;
} scan_type;
long info_mask_separate;
#define INDIO_ALL_BUFFER_MODES \
(INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE)
+#define INDIO_MAX_RAW_ELEMENTS 4
+
struct iio_trigger; /* forward declaration */
struct iio_dev;
* the channel in question. Return value will specify the
* type of value returned by the device. val and val2 will
* contain the elements making up the returned value.
+ * @read_raw_multi: function to return values from the device.
+ * mask specifies which value. Note 0 means a reading of
+ * the channel in question. Return value will specify the
+ * type of value returned by the device. vals pointer
+ * contain the elements making up the returned value.
+ * max_len specifies maximum number of elements
+ * vals pointer can contain. val_len is used to return
+ * length of valid elements in vals.
* @write_raw: function to write a value to the device.
* Parameters are the same as for read_raw.
* @write_raw_get_fmt: callback function to query the expected
int *val2,
long mask);
+ int (*read_raw_multi)(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int max_len,
+ int *vals,
+ int *val_len,
+ long mask);
+
int (*write_raw)(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val,
IIO_MOD_LIGHT_RED,
IIO_MOD_LIGHT_GREEN,
IIO_MOD_LIGHT_BLUE,
+ IIO_MOD_QUATERNION,
+ IIO_MOD_TEMP_AMBIENT,
+ IIO_MOD_TEMP_OBJECT,
};
enum iio_event_type {
#define IIO_VAL_INT_PLUS_MICRO 2
#define IIO_VAL_INT_PLUS_NANO 3
#define IIO_VAL_INT_PLUS_MICRO_DB 4
+#define IIO_VAL_INT_MULTIPLE 5
#define IIO_VAL_FRACTIONAL 10
#define IIO_VAL_FRACTIONAL_LOG2 11
extern cpumask_var_t irq_default_affinity;
-extern int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask);
+/* Internal implementation. Use the helpers below */
+extern int __irq_set_affinity(unsigned int irq, const struct cpumask *cpumask,
+ bool force);
+
+/**
+ * irq_set_affinity - Set the irq affinity of a given irq
+ * @irq: Interrupt to set affinity
+ * @mask: cpumask
+ *
+ * Fails if cpumask does not contain an online CPU
+ */
+static inline int
+irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+ return __irq_set_affinity(irq, cpumask, false);
+}
+
+/**
+ * irq_force_affinity - Force the irq affinity of a given irq
+ * @irq: Interrupt to set affinity
+ * @mask: cpumask
+ *
+ * Same as irq_set_affinity, but without checking the mask against
+ * online cpus.
+ *
+ * Solely for low level cpu hotplug code, where we need to make per
+ * cpu interrupts affine before the cpu becomes online.
+ */
+static inline int
+irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+ return __irq_set_affinity(irq, cpumask, true);
+}
+
extern int irq_can_set_affinity(unsigned int irq);
extern int irq_select_affinity(unsigned int irq);
* The first user that sets this to TRUE will receive all events that
* have been queued while no one was waiting for events.
*/
-int ipmi_set_gets_events(ipmi_user_t user, int val);
+int ipmi_set_gets_events(ipmi_user_t user, bool val);
/*
* Called when a new SMI is registered. This will also be called on
events from the BMC we are attached to. */
void (*request_events)(void *send_info);
+ /* Called by the upper layer when some user requires that the
+ interface watch for events, received messages, watchdog
+ pretimeouts, or not. Used by the SMI to know if it should
+ watch for these. This may be NULL if the SMI does not
+ implement it. */
+ void (*set_need_watch)(void *send_info, bool enable);
+
/* Called when the interface should go into "run to
completion" mode. If this call sets the value to true, the
interface should make sure that all messages are flushed
out and that none are pending, and any new requests are run
to completion immediately. */
- void (*set_run_to_completion)(void *send_info, int run_to_completion);
+ void (*set_run_to_completion)(void *send_info, bool run_to_completion);
/* Called to poll for work to do. This is so upper layers can
poll for operations during things like crash dumps. */
setting. The message handler does the mode handling. Note
that this is called from interrupt context, so it cannot
block. */
- void (*set_maintenance_mode)(void *send_info, int enable);
+ void (*set_maintenance_mode)(void *send_info, bool enable);
/* Tell the handler that we are using it/not using it. The
message handler get the modules that this handler belongs
extern void irq_cpu_online(void);
extern void irq_cpu_offline(void);
-extern int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *cpumask);
+extern int irq_set_affinity_locked(struct irq_data *data,
+ const struct cpumask *cpumask, bool force);
#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
void irq_move_irq(struct irq_data *data);
unsigned long qc_allocated;
unsigned int qc_active;
int nr_active_links; /* #links with active qcs */
+ unsigned int last_tag; /* track next tag hw expects */
struct ata_link link; /* host default link */
struct ata_link *slave_link; /* see ata_slave_link_init() */
/* GPIO numbers for bus pins */
unsigned int mdc;
unsigned int mdio;
+ unsigned int mdo;
+
+ bool mdc_active_low;
+ bool mdio_active_low;
+ bool mdo_active_low;
unsigned int phy_mask;
int irqs[PHY_MAX_ADDR];
MLX5_DEV_CAP_FLAG_BAD_QKEY_CNTR = 1LL << 9,
MLX5_DEV_CAP_FLAG_APM = 1LL << 17,
MLX5_DEV_CAP_FLAG_ATOMIC = 1LL << 18,
+ MLX5_DEV_CAP_FLAG_BLOCK_MCAST = 1LL << 23,
MLX5_DEV_CAP_FLAG_ON_DMND_PG = 1LL << 24,
MLX5_DEV_CAP_FLAG_CQ_MODER = 1LL << 29,
MLX5_DEV_CAP_FLAG_RESIZE_CQ = 1LL << 30,
enum {
MLX5_QP_LAT_SENSITIVE = 1 << 28,
+ MLX5_QP_BLOCK_MCAST = 1 << 30,
MLX5_QP_ENABLE_SIG = 1 << 31,
};
/*
* Copyright © 2010 ST Microelectronics
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
/* delete keymap entries */
void nf_ct_gre_keymap_destroy(struct nf_conn *ct);
-void nf_ct_gre_keymap_flush(struct net *net);
void nf_nat_need_gre(void);
#endif /* __KERNEL__ */
return NULL;
}
+static inline struct device_node *of_find_node_by_path(const char *path)
+{
+ return NULL;
+}
+
static inline struct device_node *of_get_parent(const struct device_node *node)
{
return NULL;
PHY_INTERFACE_MODE_SMII,
PHY_INTERFACE_MODE_XGMII,
PHY_INTERFACE_MODE_MOCA,
+ PHY_INTERFACE_MODE_QSGMII,
PHY_INTERFACE_MODE_MAX,
} phy_interface_t;
return "xgmii";
case PHY_INTERFACE_MODE_MOCA:
return "moca";
+ case PHY_INTERFACE_MODE_QSGMII:
+ return "qsgmii";
default:
return "unknown";
}
#else
static inline int phy_pm_runtime_get(struct phy *phy)
{
+ if (!phy)
+ return 0;
return -ENOSYS;
}
static inline int phy_pm_runtime_get_sync(struct phy *phy)
{
+ if (!phy)
+ return 0;
return -ENOSYS;
}
static inline int phy_pm_runtime_put(struct phy *phy)
{
+ if (!phy)
+ return 0;
return -ENOSYS;
}
static inline int phy_pm_runtime_put_sync(struct phy *phy)
{
+ if (!phy)
+ return 0;
return -ENOSYS;
}
static inline int phy_init(struct phy *phy)
{
+ if (!phy)
+ return 0;
return -ENOSYS;
}
static inline int phy_exit(struct phy *phy)
{
+ if (!phy)
+ return 0;
return -ENOSYS;
}
static inline int phy_power_on(struct phy *phy)
{
+ if (!phy)
+ return 0;
return -ENOSYS;
}
static inline int phy_power_off(struct phy *phy)
{
+ if (!phy)
+ return 0;
return -ENOSYS;
}
extern enum reboot_mode reboot_mode;
enum reboot_type {
- BOOT_TRIPLE = 't',
- BOOT_KBD = 'k',
- BOOT_BIOS = 'b',
- BOOT_ACPI = 'a',
- BOOT_EFI = 'e',
- BOOT_CF9 = 'p',
- BOOT_CF9_COND = 'q',
+ BOOT_TRIPLE = 't',
+ BOOT_KBD = 'k',
+ BOOT_BIOS = 'b',
+ BOOT_ACPI = 'a',
+ BOOT_EFI = 'e',
+ BOOT_CF9_FORCE = 'p',
+ BOOT_CF9_SAFE = 'q',
};
extern enum reboot_type reboot_type;
static inline struct regulator *__must_check
regulator_get_optional(struct device *dev, const char *id)
{
- return NULL;
+ return ERR_PTR(-ENODEV);
}
static inline struct regulator *__must_check
devm_regulator_get_optional(struct device *dev, const char *id)
{
- return NULL;
+ return ERR_PTR(-ENODEV);
}
static inline void regulator_put(struct regulator *regulator)
char name[32];
char phys[32];
+ char firmware_id[128];
bool manual_bind;
#ifdef CONFIG_SYSFS
-int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
- void *data, struct module *owner);
-
int __must_check sysfs_create_dir_ns(struct kobject *kobj, const void *ns);
void sysfs_remove_dir(struct kobject *kobj);
int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
#else /* CONFIG_SYSFS */
-static inline int sysfs_schedule_callback(struct kobject *kobj,
- void (*func)(void *), void *data, struct module *owner)
-{
- return -ENOSYS;
-}
-
static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
{
return 0;
struct tty_buffer *head; /* Queue head */
struct work_struct work;
struct mutex lock;
+ spinlock_t flush_lock;
atomic_t priority;
struct tty_buffer sentinel;
struct llist_head free; /* Free queue head */
(!__builtin_constant_p(state) || \
state == TASK_INTERRUPTIBLE || state == TASK_KILLABLE) \
+/*
+ * The below macro ___wait_event() has an explicit shadow of the __ret
+ * variable when used from the wait_event_*() macros.
+ *
+ * This is so that both can use the ___wait_cond_timeout() construct
+ * to wrap the condition.
+ *
+ * The type inconsistency of the wait_event_*() __ret variable is also
+ * on purpose; we use long where we can return timeout values and int
+ * otherwise.
+ */
+
#define ___wait_event(wq, condition, state, exclusive, ret, cmd) \
({ \
__label__ __out; \
wait_queue_t __wait; \
- long __ret = ret; \
+ long __ret = ret; /* explicit shadow */ \
\
INIT_LIST_HEAD(&__wait.task_list); \
if (exclusive) \
void *__pad1;
#endif
int (*input)(struct sk_buff *);
- int (*output)(struct sk_buff *);
+ int (*output)(struct sock *sk, struct sk_buff *skb);
unsigned short flags;
#define DST_HOST 0x0001
return child;
}
-int dst_discard(struct sk_buff *skb);
+int dst_discard_sk(struct sock *sk, struct sk_buff *skb);
+static inline int dst_discard(struct sk_buff *skb)
+{
+ return dst_discard_sk(skb->sk, skb);
+}
void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref,
int initial_obsolete, unsigned short flags);
void __dst_free(struct dst_entry *dst);
}
/* Output packet to network from transport. */
+static inline int dst_output_sk(struct sock *sk, struct sk_buff *skb)
+{
+ return skb_dst(skb)->output(sk, skb);
+}
static inline int dst_output(struct sk_buff *skb)
{
- return skb_dst(skb)->output(skb);
+ return dst_output_sk(skb->sk, skb);
}
/* Input packet from network to transport. */
#include <linux/in6.h>
#include <linux/atomic.h>
+/*
+ * ifindex generation is per-net namespace, and loopback is
+ * always the 1st device in ns (see net_dev_init), thus any
+ * loopback device should get ifindex 1
+ */
+
+#define LOOPBACK_IFINDEX 1
+
struct flowi_common {
int flowic_oif;
int flowic_iif;
__be16 dport, __be16 sport)
{
fl4->flowi4_oif = oif;
- fl4->flowi4_iif = 0;
+ fl4->flowi4_iif = LOOPBACK_IFINDEX;
fl4->flowi4_mark = mark;
fl4->flowi4_tos = tos;
fl4->flowi4_scope = scope;
void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
-int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl);
+int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl);
struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu);
#endif /* _INET6_CONNECTION_SOCK_H */
* (i.e. things that depend on the address family)
*/
struct inet_connection_sock_af_ops {
- int (*queue_xmit)(struct sk_buff *skb, struct flowi *fl);
+ int (*queue_xmit)(struct sock *sk, struct sk_buff *skb, struct flowi *fl);
void (*send_check)(struct sock *sk, struct sk_buff *skb);
int (*rebuild_header)(struct sock *sk);
void (*sk_rx_dst_set)(struct sock *sk, const struct sk_buff *skb);
struct net_device *orig_dev);
int ip_local_deliver(struct sk_buff *skb);
int ip_mr_input(struct sk_buff *skb);
-int ip_output(struct sk_buff *skb);
-int ip_mc_output(struct sk_buff *skb);
+int ip_output(struct sock *sk, struct sk_buff *skb);
+int ip_mc_output(struct sock *sk, struct sk_buff *skb);
int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
int ip_do_nat(struct sk_buff *skb);
void ip_send_check(struct iphdr *ip);
int __ip_local_out(struct sk_buff *skb);
-int ip_local_out(struct sk_buff *skb);
-int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl);
+int ip_local_out_sk(struct sock *sk, struct sk_buff *skb);
+static inline int ip_local_out(struct sk_buff *skb)
+{
+ return ip_local_out_sk(skb->sk, skb);
+}
+
+int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl);
void ip_init(void);
int ip_append_data(struct sock *sk, struct flowi4 *fl4,
int getfrag(void *from, char *to, int offset, int len,
#define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010
#define RT6_LOOKUP_F_SRCPREF_COA 0x00000020
+/* We do not (yet ?) support IPv6 jumbograms (RFC 2675)
+ * Unlike IPv4, hdr->seg_len doesn't include the IPv6 header
+ */
+#define IP6_MAX_MTU (0xFFFF + sizeof(struct ipv6hdr))
+
/*
* rt6_srcprefs2flags() and rt6_flags2srcprefs() translate
* between IPV6_ADDR_PREFERENCES socket option values
}
int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto);
-int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb,
+int iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 proto,
__u8 tos, __u8 ttl, __be16 df, bool xnet);
* skb processing functions
*/
-int ip6_output(struct sk_buff *skb);
+int ip6_output(struct sock *sk, struct sk_buff *skb);
int ip6_forward(struct sk_buff *skb);
int ip6_input(struct sk_buff *skb);
int ip6_mc_input(struct sk_buff *skb);
#include <linux/list.h>
#include <linux/sysctl.h>
+#include <net/flow.h>
#include <net/netns/core.h>
#include <net/netns/mib.h>
#include <net/netns/unix.h>
atomic_t fnhe_genid;
};
-/*
- * ifindex generation is per-net namespace, and loopback is
- * always the 1st device in ns (see net_dev_init), thus any
- * loopback device should get ifindex 1
- */
-
-#define LOOPBACK_IFINDEX 1
-
#include <linux/seq_file_net.h>
/* Init's network namespace */
u8 len;
};
+/* Calculate the mask for the nft_cmp_fast expression. On big endian the
+ * mask needs to include the *upper* bytes when interpreting that data as
+ * something smaller than the full u32, therefore a cpu_to_le32 is done.
+ */
+static inline u32 nft_cmp_fast_mask(unsigned int len)
+{
+ return cpu_to_le32(~0U >> (FIELD_SIZEOF(struct nft_cmp_fast_expr,
+ data) * BITS_PER_BYTE - len));
+}
+
extern const struct nft_expr_ops nft_cmp_fast_ops;
int nft_cmp_module_init(void);
/* SCTP-AUTH: endpoint shared keys */
struct list_head endpoint_shared_keys;
__u16 active_key_id;
+ __u8 auth_enable;
};
/* Recover the outter endpoint structure. */
int sctp_has_association(struct net *net, const union sctp_addr *laddr,
const union sctp_addr *paddr);
-int sctp_verify_init(struct net *net, const struct sctp_association *asoc,
+int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep,
+ const struct sctp_association *asoc,
sctp_cid_t, sctp_init_chunk_t *peer_init,
struct sctp_chunk *chunk, struct sctp_chunk **err_chunk);
int sctp_process_init(struct sctp_association *, struct sctp_chunk *chunk,
/* This is the last advertised value of rwnd over a SACK chunk. */
__u32 a_rwnd;
+ /* Number of bytes by which the rwnd has slopped. The rwnd is allowed
+ * to slop over a maximum of the association's frag_point.
+ */
+ __u32 rwnd_over;
+
+ /* Keeps treack of rwnd pressure. This happens when we have
+ * a window, but not recevie buffer (i.e small packets). This one
+ * is releases slowly (1 PMTU at a time ).
+ */
+ __u32 rwnd_press;
+
/* This is the sndbuf size in use for the association.
* This corresponds to the sndbuf size for the association,
* as specified in the sk->sndbuf.
__u32 sctp_association_get_next_tsn(struct sctp_association *);
void sctp_assoc_sync_pmtu(struct sock *, struct sctp_association *);
-void sctp_assoc_rwnd_update(struct sctp_association *, bool);
+void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned int);
+void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned int);
void sctp_assoc_set_primary(struct sctp_association *,
struct sctp_transport *);
void sctp_assoc_del_nonprimary_peers(struct sctp_association *,
const xfrm_address_t *saddr);
int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
- int (*output)(struct sk_buff *skb);
+ int (*output)(struct sock *sk, struct sk_buff *skb);
int (*output_finish)(struct sk_buff *skb);
int (*extract_input)(struct xfrm_state *x,
struct sk_buff *skb);
int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb);
int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
-int xfrm4_output(struct sk_buff *skb);
+int xfrm4_output(struct sock *sk, struct sk_buff *skb);
int xfrm4_output_finish(struct sk_buff *skb);
int xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err);
int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol);
__be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr);
int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb);
int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
-int xfrm6_output(struct sk_buff *skb);
+int xfrm6_output(struct sock *sk, struct sk_buff *skb);
int xfrm6_output_finish(struct sk_buff *skb);
int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
u8 **prevhdr);
struct ext4_map_blocks;
struct extent_status;
-/* shim until we merge in the xfs_collapse_range branch */
-#ifndef FALLOC_FL_COLLAPSE_RANGE
-#define FALLOC_FL_COLLAPSE_RANGE 0x08
-#endif
-
-#ifndef FALLOC_FL_ZERO_RANGE
-#define FALLOC_FL_ZERO_RANGE 0x10
-#endif
-
#define EXT4_I(inode) (container_of(inode, struct ext4_inode_info, vfs_inode))
#define show_mballoc_flags(flags) __print_flags(flags, "|", \
#endif
/*
- * fd "private" POSIX locks.
+ * Open File Description Locks
*
- * Usually POSIX locks held by a process are released on *any* close and are
+ * Usually record locks held by a process are released on *any* close and are
* not inherited across a fork().
*
- * These cmd values will set locks that conflict with normal POSIX locks, but
- * are "owned" by the opened file, not the process. This means that they are
- * inherited across fork() like BSD (flock) locks, and they are only released
- * automatically when the last reference to the the open file against which
- * they were acquired is put.
+ * These cmd values will set locks that conflict with process-associated
+ * record locks, but are "owned" by the open file description, not the
+ * process. This means that they are inherited across fork() like BSD (flock)
+ * locks, and they are only released automatically when the last reference to
+ * the the open file against which they were acquired is put.
*/
-#define F_GETLKP 36
-#define F_SETLKP 37
-#define F_SETLKPW 38
+#define F_OFD_GETLK 36
+#define F_OFD_SETLK 37
+#define F_OFD_SETLKW 38
#define F_OWNER_TID 0
#define F_OWNER_PID 1
__u32 num_waitchks;
__u32 waitchk_mask;
__u32 timeout;
- __u32 pad;
__u64 syncpts;
__u64 cmdbufs;
__u64 relocs;
#define HV_ERROR_DEVICE_NOT_CONNECTED 0x8007048F
#define HV_INVALIDARG 0x80070057
#define HV_GUID_NOTFOUND 0x80041002
+#define HV_ERROR_ALREADY_EXISTS 0x80070050
#define ADDR_FAMILY_NONE 0x00
#define ADDR_FAMILY_IPV4 0x01
#define INPUT_PROP_DIRECT 0x01 /* direct input devices */
#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */
#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
+#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
#define INPUT_PROP_MAX 0x1f
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
See Documentation/nommu-mmap.txt for more information.
+config SYSTEM_TRUSTED_KEYRING
+ bool "Provide system-wide ring of trusted keys"
+ depends on KEYS
+ help
+ Provide a system keyring to which trusted keys can be added. Keys in
+ the keyring are considered to be trusted. Keys may be added at will
+ by the kernel from compiled-in data and from hardware key stores, but
+ userspace may only add extra keys if those keys can be verified by
+ keys already in the keyring.
+
+ Keys in this keyring are used by module signature checking.
+
config PROFILING
bool "Profiling support"
help
default 0 if BASE_FULL
default 1 if !BASE_FULL
-config SYSTEM_TRUSTED_KEYRING
- bool "Provide system-wide ring of trusted keys"
- depends on KEYS
- help
- Provide a system keyring to which trusted keys can be added. Keys in
- the keyring are considered to be trusted. Keys may be added at will
- by the kernel from compiled-in data and from hardware key stores, but
- userspace may only add extra keys if those keys can be verified by
- keys already in the keyring.
-
- Keys in this keyring are used by module signature checking.
-
menuconfig MODULES
bool "Enable loadable module support"
option modules
struct irq_chip *chip = irq_data_get_irq_chip(data);
int ret;
- ret = chip->irq_set_affinity(data, mask, false);
+ ret = chip->irq_set_affinity(data, mask, force);
switch (ret) {
case IRQ_SET_MASK_OK:
cpumask_copy(data->affinity, mask);
return ret;
}
-int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask)
+int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask,
+ bool force)
{
struct irq_chip *chip = irq_data_get_irq_chip(data);
struct irq_desc *desc = irq_data_to_desc(data);
return -EINVAL;
if (irq_can_move_pcntxt(data)) {
- ret = irq_do_set_affinity(data, mask, false);
+ ret = irq_do_set_affinity(data, mask, force);
} else {
irqd_set_move_pending(data);
irq_copy_pending(desc, mask);
return ret;
}
-/**
- * irq_set_affinity - Set the irq affinity of a given irq
- * @irq: Interrupt to set affinity
- * @mask: cpumask
- *
- */
-int irq_set_affinity(unsigned int irq, const struct cpumask *mask)
+int __irq_set_affinity(unsigned int irq, const struct cpumask *mask, bool force)
{
struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
return -EINVAL;
raw_spin_lock_irqsave(&desc->lock, flags);
- ret = __irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask);
+ ret = irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask, force);
raw_spin_unlock_irqrestore(&desc->lock, flags);
return ret;
}
void debug_mutex_unlock(struct mutex *lock)
{
- if (unlikely(!debug_locks))
- return;
+ if (likely(debug_locks)) {
+ DEBUG_LOCKS_WARN_ON(lock->magic != lock);
- DEBUG_LOCKS_WARN_ON(lock->magic != lock);
+ if (!lock->owner)
+ DEBUG_LOCKS_WARN_ON(!lock->owner);
+ else
+ DEBUG_LOCKS_WARN_ON(lock->owner != current);
- if (!lock->owner)
- DEBUG_LOCKS_WARN_ON(!lock->owner);
- else
- DEBUG_LOCKS_WARN_ON(lock->owner != current);
-
- DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);
- mutex_clear_owner(lock);
+ DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);
+ mutex_clear_owner(lock);
+ }
/*
* __mutex_slowpath_needs_to_unlock() is explicitly 0 for debug
#include <linux/init.h>
#include <linux/console.h>
#include <linux/cpu.h>
+#include <linux/cpuidle.h>
#include <linux/syscalls.h>
#include <linux/gfp.h>
#include <linux/io.h>
static void freeze_enter(void)
{
+ cpuidle_resume();
wait_event(suspend_freeze_wait_head, suspend_freeze_wake);
+ cpuidle_pause();
}
void freeze_wake(void)
dl_rq = &rq->dl;
- if (need_pull_dl_task(rq, prev))
+ if (need_pull_dl_task(rq, prev)) {
pull_dl_task(rq);
+ /*
+ * pull_rt_task() can drop (and re-acquire) rq->lock; this
+ * means a stop task can slip in, in which case we need to
+ * re-start task selection.
+ */
+ if (rq->stop && rq->stop->on_rq)
+ return RETRY_TASK;
+ }
+
/*
* When prev is DL, we may throttle it in put_prev_task().
* So, we update time before we check for dl_nr_running.
/* If the task is part of a group prevent parallel updates to group stats */
if (p->numa_group) {
group_lock = &p->numa_group->lock;
- spin_lock(group_lock);
+ spin_lock_irq(group_lock);
}
/* Find the node with the highest number of faults */
}
}
- spin_unlock(group_lock);
+ spin_unlock_irq(group_lock);
}
/* Preferred node as the node with the most faults */
if (!join)
return;
- double_lock(&my_grp->lock, &grp->lock);
+ BUG_ON(irqs_disabled());
+ double_lock_irq(&my_grp->lock, &grp->lock);
for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++) {
my_grp->faults[i] -= p->numa_faults_memory[i];
grp->nr_tasks++;
spin_unlock(&my_grp->lock);
- spin_unlock(&grp->lock);
+ spin_unlock_irq(&grp->lock);
rcu_assign_pointer(p->numa_group, grp);
void *numa_faults = p->numa_faults_memory;
if (grp) {
- spin_lock(&grp->lock);
+ spin_lock_irq(&grp->lock);
for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++)
grp->faults[i] -= p->numa_faults_memory[i];
grp->total_faults -= p->total_numa_faults;
list_del(&p->numa_entry);
grp->nr_tasks--;
- spin_unlock(&grp->lock);
+ spin_unlock_irq(&grp->lock);
rcu_assign_pointer(p->numa_group, NULL);
put_numa_group(grp);
}
out:
/* Is there a task of a high priority class? */
if (this_rq->nr_running != this_rq->cfs.h_nr_running &&
- (this_rq->dl.dl_nr_running ||
+ ((this_rq->stop && this_rq->stop->on_rq) ||
+ this_rq->dl.dl_nr_running ||
(this_rq->rt.rt_nr_running && !rt_rq_throttled(&this_rq->rt))))
pulled_task = -1;
pull_rt_task(rq);
/*
* pull_rt_task() can drop (and re-acquire) rq->lock; this
- * means a dl task can slip in, in which case we need to
- * re-start task selection.
+ * means a dl or stop task can slip in, in which case we need
+ * to re-start task selection.
*/
- if (unlikely(rq->dl.dl_nr_running))
+ if (unlikely((rq->stop && rq->stop->on_rq) ||
+ rq->dl.dl_nr_running))
return RETRY_TASK;
}
spin_lock_nested(l2, SINGLE_DEPTH_NESTING);
}
+static inline void double_lock_irq(spinlock_t *l1, spinlock_t *l2)
+{
+ if (l1 > l2)
+ swap(l1, l2);
+
+ spin_lock_irq(l1);
+ spin_lock_nested(l2, SINGLE_DEPTH_NESTING);
+}
+
static inline void double_raw_lock(raw_spinlock_t *l1, raw_spinlock_t *l2)
{
if (l1 > l2)
{
struct task_struct *task = current;
struct pt_regs *regs = task_pt_regs(task);
+ unsigned long args[6];
sd->nr = syscall_get_nr(task, regs);
sd->arch = syscall_get_arch();
-
- /* Unroll syscall_get_args to help gcc on arm. */
- syscall_get_arguments(task, regs, 0, 1, (unsigned long *) &sd->args[0]);
- syscall_get_arguments(task, regs, 1, 1, (unsigned long *) &sd->args[1]);
- syscall_get_arguments(task, regs, 2, 1, (unsigned long *) &sd->args[2]);
- syscall_get_arguments(task, regs, 3, 1, (unsigned long *) &sd->args[3]);
- syscall_get_arguments(task, regs, 4, 1, (unsigned long *) &sd->args[4]);
- syscall_get_arguments(task, regs, 5, 1, (unsigned long *) &sd->args[5]);
-
+ syscall_get_arguments(task, regs, 0, 6, args);
+ sd->args[0] = args[0];
+ sd->args[1] = args[1];
+ sd->args[2] = args[2];
+ sd->args[3] = args[3];
+ sd->args[4] = args[4];
+ sd->args[5] = args[5];
sd->instruction_pointer = KSTK_EIP(task);
}
goto free_prog;
/* Allocate a new seccomp_filter */
+ ret = -ENOMEM;
filter = kzalloc(sizeof(struct seccomp_filter) +
sizeof(struct sock_filter_int) * new_len,
GFP_KERNEL|__GFP_NOWARN);
ret = sk_convert_filter(fp, fprog->len, filter->insnsi, &new_len);
if (ret)
goto free_filter;
+ kfree(fp);
atomic_set(&filter->usage, 1);
filter->len = new_len;
bool tick_check_replacement(struct clock_event_device *curdev,
struct clock_event_device *newdev)
{
- if (tick_check_percpu(curdev, newdev, smp_processor_id()))
+ if (!tick_check_percpu(curdev, newdev, smp_processor_id()))
return false;
return tick_check_preferred(curdev, newdev);
/* Keep the tick_next_period variable up to date */
tick_next_period = ktime_add(last_jiffies_update, tick_period);
+ } else {
+ write_sequnlock(&jiffies_lock);
+ return;
}
write_sequnlock(&jiffies_lock);
update_wall_time();
struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
ktime_t next;
- if (!tick_nohz_active)
+ if (!tick_nohz_enabled)
return;
local_irq_disable();
{
int ret;
- /* The top level array uses the "global_ops". */
- if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL)) {
- ret = allocate_ftrace_ops(tr);
- if (ret)
- return ret;
- }
+ /*
+ * The top level array uses the "global_ops", and the files are
+ * created on boot up.
+ */
+ if (tr->flags & TRACE_ARRAY_FL_GLOBAL)
+ return 0;
+
+ ret = allocate_ftrace_ops(tr);
+ if (ret)
+ return ret;
ftrace_create_filter_files(tr->ops, parent);
static void uprobe_buffer_disable(void)
{
+ int cpu;
+
BUG_ON(!mutex_is_locked(&event_mutex));
if (--uprobe_buffer_refcnt == 0) {
+ for_each_possible_cpu(cpu)
+ free_page((unsigned long)per_cpu_ptr(uprobe_cpu_buffer,
+ cpu)->buf);
+
free_percpu(uprobe_cpu_buffer);
uprobe_cpu_buffer = NULL;
}
/* Find the matching extent */
extents = map->nr_extents;
- smp_read_barrier_depends();
+ smp_rmb();
for (idx = 0; idx < extents; idx++) {
first = map->extent[idx].first;
last = first + map->extent[idx].count - 1;
/* Find the matching extent */
extents = map->nr_extents;
- smp_read_barrier_depends();
+ smp_rmb();
for (idx = 0; idx < extents; idx++) {
first = map->extent[idx].first;
last = first + map->extent[idx].count - 1;
/* Find the matching extent */
extents = map->nr_extents;
- smp_read_barrier_depends();
+ smp_rmb();
for (idx = 0; idx < extents; idx++) {
first = map->extent[idx].lower_first;
last = first + map->extent[idx].count - 1;
* were written before the count of the extents.
*
* To achieve this smp_wmb() is used on guarantee the write
- * order and smp_read_barrier_depends() is guaranteed that we
- * don't have crazy architectures returning stale data.
- *
+ * order and smp_rmb() is guaranteed that we don't have crazy
+ * architectures returning stale data.
*/
mutex_lock(&id_map_mutex);
void touch_softlockup_watchdog(void)
{
- __this_cpu_write(watchdog_touch_ts, 0);
+ /*
+ * Preemption can be enabled. It doesn't matter which CPU's timestamp
+ * gets zeroed here, so use the raw_ operation.
+ */
+ raw_cpu_write(watchdog_touch_ts, 0);
}
EXPORT_SYMBOL(touch_softlockup_watchdog);
bool "Debug VM red-black trees"
depends on DEBUG_VM
help
- Enable this to turn on more extended checks in the virtual-memory
- system that may impact performance.
+ Enable VM red-black tree debugging information and extra validations.
If unsure, say N.
* @iocb: IO state structure (file, offset, etc.)
* @iov: vector with data to write
* @nr_segs: number of segments in the vector
- * @ppos: position where to write
*
* This function does all the work needed for actually writing data to a
* file. It does all basic checks, removes SUID from the file, updates
enum page_check_address_pmd_flag flag,
spinlock_t **ptl)
{
+ pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
if (address & ~HPAGE_PMD_MASK)
return NULL;
- pmd = mm_find_pmd(mm, address);
- if (!pmd)
+ pgd = pgd_offset(mm, address);
+ if (!pgd_present(*pgd))
return NULL;
+ pud = pud_offset(pgd, address);
+ if (!pud_present(*pud))
+ return NULL;
+ pmd = pmd_offset(pud, address);
+
*ptl = pmd_lock(mm, pmd);
- if (pmd_none(*pmd))
+ if (!pmd_present(*pmd))
goto unlock;
if (pmd_page(*pmd) != page)
goto unlock;
while (nr_pages--) {
if (!free_pool_huge_page(h, &node_states[N_MEMORY], 1))
break;
+ cond_resched_lock(&hugetlb_lock);
}
}
#endif
}
-void tlb_flush_mmu(struct mmu_gather *tlb)
+static void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
{
- struct mmu_gather_batch *batch;
-
- if (!tlb->need_flush)
- return;
tlb->need_flush = 0;
tlb_flush(tlb);
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
tlb_table_flush(tlb);
#endif
+}
+
+static void tlb_flush_mmu_free(struct mmu_gather *tlb)
+{
+ struct mmu_gather_batch *batch;
for (batch = &tlb->local; batch; batch = batch->next) {
free_pages_and_swap_cache(batch->pages, batch->nr);
tlb->active = &tlb->local;
}
+void tlb_flush_mmu(struct mmu_gather *tlb)
+{
+ if (!tlb->need_flush)
+ return;
+ tlb_flush_mmu_tlbonly(tlb);
+ tlb_flush_mmu_free(tlb);
+}
+
/* tlb_finish_mmu
* Called at the end of the shootdown operation to free up any resources
* that were required.
if (PageAnon(page))
rss[MM_ANONPAGES]--;
else {
- if (pte_dirty(ptent))
+ if (pte_dirty(ptent)) {
+ force_flush = 1;
set_page_dirty(page);
+ }
if (pte_young(ptent) &&
likely(!(vma->vm_flags & VM_SEQ_READ)))
mark_page_accessed(page);
page_remove_rmap(page);
if (unlikely(page_mapcount(page) < 0))
print_bad_pte(vma, addr, ptent, page);
- force_flush = !__tlb_remove_page(tlb, page);
- if (force_flush)
+ if (unlikely(!__tlb_remove_page(tlb, page))) {
+ force_flush = 1;
break;
+ }
continue;
}
/*
add_mm_rss_vec(mm, rss);
arch_leave_lazy_mmu_mode();
- pte_unmap_unlock(start_pte, ptl);
- /*
- * mmu_gather ran out of room to batch pages, we break out of
- * the PTE lock to avoid doing the potential expensive TLB invalidate
- * and page-free while holding it.
- */
+ /* Do the actual TLB flush before dropping ptl */
if (force_flush) {
unsigned long old_end;
- force_flush = 0;
-
/*
* Flush the TLB just for the previous segment,
* then update the range to be the remaining
*/
old_end = tlb->end;
tlb->end = addr;
-
- tlb_flush_mmu(tlb);
-
+ tlb_flush_mmu_tlbonly(tlb);
tlb->start = addr;
tlb->end = old_end;
+ }
+ pte_unmap_unlock(start_pte, ptl);
+
+ /*
+ * If we forced a TLB flush (either due to running out of
+ * batch buffers or because we needed to flush dirty TLB
+ * entries before releasing the ptl), free the batched
+ * memory too. Restart if we didn't do everything.
+ */
+ if (force_flush) {
+ force_flush = 0;
+ tlb_flush_mmu_free(tlb);
if (addr != end)
goto again;
unsigned long address, unsigned int fault_flags)
{
struct vm_area_struct *vma;
+ vm_flags_t vm_flags;
int ret;
vma = find_extend_vma(mm, address);
if (!vma || address < vma->vm_start)
return -EFAULT;
+ vm_flags = (fault_flags & FAULT_FLAG_WRITE) ? VM_WRITE : VM_READ;
+ if (!(vm_flags & vma->vm_flags))
+ return -EFAULT;
+
ret = handle_mm_fault(mm, vma, address, fault_flags);
if (ret & VM_FAULT_ERROR) {
if (ret & VM_FAULT_OOM)
TTU_UNMAP|TTU_IGNORE_ACCESS,
&dummy1, &dummy2, &dummy3, &dummy4, &dummy5, true);
list_splice(&clean_pages, page_list);
- __mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret);
+ mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret);
return ret;
}
}
}
+static int vlan_calculate_locking_subclass(struct net_device *real_dev)
+{
+ int subclass = 0;
+
+ while (is_vlan_dev(real_dev)) {
+ subclass++;
+ real_dev = vlan_dev_priv(real_dev)->real_dev;
+ }
+
+ return subclass;
+}
+
+static void vlan_dev_mc_sync(struct net_device *to, struct net_device *from)
+{
+ int err = 0, subclass;
+
+ subclass = vlan_calculate_locking_subclass(to);
+
+ spin_lock_nested(&to->addr_list_lock, subclass);
+ err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len);
+ if (!err)
+ __dev_set_rx_mode(to);
+ spin_unlock(&to->addr_list_lock);
+}
+
+static void vlan_dev_uc_sync(struct net_device *to, struct net_device *from)
+{
+ int err = 0, subclass;
+
+ subclass = vlan_calculate_locking_subclass(to);
+
+ spin_lock_nested(&to->addr_list_lock, subclass);
+ err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len);
+ if (!err)
+ __dev_set_rx_mode(to);
+ spin_unlock(&to->addr_list_lock);
+}
+
static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
{
- dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
- dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
+ vlan_dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
+ vlan_dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
}
/*
SET_NETDEV_DEVTYPE(dev, &vlan_type);
- if (is_vlan_dev(real_dev))
- subclass = 1;
-
+ subclass = vlan_calculate_locking_subclass(dev);
vlan_dev_set_lockdep_class(dev, subclass);
vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
__be16 skb_network_protocol(struct sk_buff *skb, int *depth)
{
__be16 type = skb->protocol;
- int vlan_depth = ETH_HLEN;
+ int vlan_depth = skb->mac_len;
/* Tunnel gso handlers can set protocol to ethernet. */
if (type == htons(ETH_P_TEB)) {
if (ops->ndo_set_rx_mode)
ops->ndo_set_rx_mode(dev);
}
+EXPORT_SYMBOL(__dev_set_rx_mode);
void dev_set_rx_mode(struct net_device *dev)
{
mutex_unlock(&dst_gc_mutex);
}
-int dst_discard(struct sk_buff *skb)
+int dst_discard_sk(struct sock *sk, struct sk_buff *skb)
{
kfree_skb(skb);
return 0;
}
-EXPORT_SYMBOL(dst_discard);
+EXPORT_SYMBOL(dst_discard_sk);
const u32 dst_default_metrics[RTAX_MAX + 1] = {
/* This initializer is needed to force linker to place this variable
dst->xfrm = NULL;
#endif
dst->input = dst_discard;
- dst->output = dst_discard;
+ dst->output = dst_discard_sk;
dst->error = 0;
dst->obsolete = initial_obsolete;
dst->header_len = 0;
/* The first case (dev==NULL) is required, when
protocol module is unloaded.
*/
- if (dst->dev == NULL || !(dst->dev->flags&IFF_UP))
- dst->input = dst->output = dst_discard;
+ if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) {
+ dst->input = dst_discard;
+ dst->output = dst_discard_sk;
+ }
dst->obsolete = DST_OBSOLETE_DEAD;
}
return;
if (!unregister) {
- dst->input = dst->output = dst_discard;
+ dst->input = dst_discard;
+ dst->output = dst_discard_sk;
} else {
dst->dev = dev_net(dst->dev)->loopback_dev;
dev_hold(dst->dev);
if (skb_is_nonlinear(skb))
return 0;
+ if (skb->len < sizeof(struct nlattr))
+ return 0;
+
if (A > skb->len - sizeof(struct nlattr))
return 0;
if (skb_is_nonlinear(skb))
return 0;
+ if (skb->len < sizeof(struct nlattr))
+ return 0;
+
if (A > skb->len - sizeof(struct nlattr))
return 0;
nla = (struct nlattr *) &skb->data[A];
- if (nla->nla_len > A - skb->len)
+ if (nla->nla_len > skb->len - A)
return 0;
nla = nla_find_nested(nla, X);
[BPF_S_ANC_RXHASH] = BPF_LD|BPF_B|BPF_ABS,
[BPF_S_ANC_CPU] = BPF_LD|BPF_B|BPF_ABS,
[BPF_S_ANC_ALU_XOR_X] = BPF_LD|BPF_B|BPF_ABS,
- [BPF_S_ANC_SECCOMP_LD_W] = BPF_LD|BPF_B|BPF_ABS,
[BPF_S_ANC_VLAN_TAG] = BPF_LD|BPF_B|BPF_ABS,
[BPF_S_ANC_VLAN_TAG_PRESENT] = BPF_LD|BPF_B|BPF_ABS,
[BPF_S_ANC_PAY_OFFSET] = BPF_LD|BPF_B|BPF_ABS,
DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
- err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl);
+ err = icsk->icsk_af_ops->queue_xmit(sk, skb, &inet->cork.fl);
return net_xmit_eval(err);
}
return -ENOBUFS;
return n->output(n, skb);
}
-static int dn_output(struct sk_buff *skb)
+static int dn_output(struct sock *sk, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
struct dn_route *rt = (struct dn_route *)dst;
* Used to catch bugs. This should never normally get
* called.
*/
+static int dn_rt_bug_sk(struct sock *sk, struct sk_buff *skb)
+{
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
+
+ net_dbg_ratelimited("dn_rt_bug: skb from:%04x to:%04x\n",
+ le16_to_cpu(cb->src), le16_to_cpu(cb->dst));
+
+ kfree_skb(skb);
+
+ return NET_RX_DROP;
+}
+
static int dn_rt_bug(struct sk_buff *skb)
{
struct dn_skb_cb *cb = DN_SKB_CB(skb);
rt->n = neigh;
rt->dst.lastuse = jiffies;
- rt->dst.output = dn_rt_bug;
+ rt->dst.output = dn_rt_bug_sk;
switch (res.type) {
case RTN_UNICAST:
rt->dst.input = dn_forward;
bool dev_match;
fl4.flowi4_oif = 0;
- fl4.flowi4_iif = oif;
+ fl4.flowi4_iif = oif ? : LOOPBACK_IFINDEX;
fl4.daddr = src;
fl4.saddr = dst;
fl4.flowi4_tos = tos;
.daddr = nh->nh_gw,
.flowi4_scope = cfg->fc_scope + 1,
.flowi4_oif = nh->nh_oif,
+ .flowi4_iif = LOOPBACK_IFINDEX,
};
/* It is not necessary, but requires a bit of thinking */
skb_dst(skb)->dev, dst_output);
}
-int ip_local_out(struct sk_buff *skb)
+int ip_local_out_sk(struct sock *sk, struct sk_buff *skb)
{
int err;
err = __ip_local_out(skb);
if (likely(err == 1))
- err = dst_output(skb);
+ err = dst_output_sk(sk, skb);
return err;
}
-EXPORT_SYMBOL_GPL(ip_local_out);
+EXPORT_SYMBOL_GPL(ip_local_out_sk);
static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst)
{
return ip_finish_output2(skb);
}
-int ip_mc_output(struct sk_buff *skb)
+int ip_mc_output(struct sock *sk, struct sk_buff *skb)
{
- struct sock *sk = skb->sk;
struct rtable *rt = skb_rtable(skb);
struct net_device *dev = rt->dst.dev;
!(IPCB(skb)->flags & IPSKB_REROUTED));
}
-int ip_output(struct sk_buff *skb)
+int ip_output(struct sock *sk, struct sk_buff *skb)
{
struct net_device *dev = skb_dst(skb)->dev;
sizeof(fl4->saddr) + sizeof(fl4->daddr));
}
-int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl)
+/* Note: skb->sk can be different from sk, in case of tunnels */
+int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl)
{
- struct sock *sk = skb->sk;
struct inet_sock *inet = inet_sk(sk);
struct ip_options_rcu *inet_opt;
struct flowi4 *fl4;
ip_select_ident_more(skb, &rt->dst, sk,
(skb_shinfo(skb)->gso_segs ?: 1) - 1);
+ /* TODO : should we use skb->sk here instead of sk ? */
skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark;
return;
}
- err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, protocol,
+ err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, protocol,
tos, ttl, df, !net_eq(tunnel->net, dev_net(dev)));
iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
{
int err = 0;
- struct ip_tunnel *t;
- struct net *net = dev_net(dev);
- struct ip_tunnel *tunnel = netdev_priv(dev);
- struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
+ struct ip_tunnel *t = netdev_priv(dev);
+ struct net *net = t->net;
+ struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id);
BUG_ON(!itn->fb_tunnel_dev);
switch (cmd) {
case SIOCGETTUNNEL:
- t = NULL;
- if (dev == itn->fb_tunnel_dev)
+ if (dev == itn->fb_tunnel_dev) {
t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
- if (t == NULL)
- t = netdev_priv(dev);
+ if (t == NULL)
+ t = netdev_priv(dev);
+ }
memcpy(p, &t->parms, sizeof(*p));
break;
#include <net/netns/generic.h>
#include <net/rtnetlink.h>
-int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb,
+int iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 proto,
__u8 tos, __u8 ttl, __be16 df, bool xnet)
{
iph->ttl = ttl;
__ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1);
- err = ip_local_out(skb);
+ err = ip_local_out_sk(sk, skb);
if (unlikely(net_xmit_eval(err)))
pkt_len = 0;
return pkt_len;
struct mr_table *mrt;
struct flowi4 fl4 = {
.flowi4_oif = dev->ifindex,
- .flowi4_iif = skb->skb_iif,
+ .flowi4_iif = skb->skb_iif ? : LOOPBACK_IFINDEX,
.flowi4_mark = skb->mark,
};
int err;
if (ipv4_is_multicast(iph->daddr)) {
if (ipv4_is_zeronet(iph->saddr))
return ipv4_is_local_multicast(iph->daddr) ^ invert;
- flow.flowi4_iif = 0;
- } else {
- flow.flowi4_iif = LOOPBACK_IFINDEX;
}
-
+ flow.flowi4_iif = LOOPBACK_IFINDEX;
flow.daddr = iph->saddr;
flow.saddr = rpfilter_get_saddr(iph->daddr);
flow.flowi4_oif = 0;
{
struct net *net = sock_net(sk);
kgid_t group = current_egid();
- struct group_info *group_info = get_current_groups();
- int i, j, count = group_info->ngroups;
+ struct group_info *group_info;
+ int i, j, count;
kgid_t low, high;
+ int ret = 0;
inet_get_ping_group_range_net(net, &low, &high);
if (gid_lte(low, group) && gid_lte(group, high))
return 0;
+ group_info = get_current_groups();
+ count = group_info->ngroups;
for (i = 0; i < group_info->nblocks; i++) {
int cp_count = min_t(int, NGROUPS_PER_BLOCK, count);
for (j = 0; j < cp_count; j++) {
kgid_t gid = group_info->blocks[i][j];
if (gid_lte(low, gid) && gid_lte(gid, high))
- return 0;
+ goto out_release_group;
}
count -= cp_count;
}
- return -EACCES;
+ ret = -EACCES;
+
+out_release_group:
+ put_group_info(group_info);
+ return ret;
}
EXPORT_SYMBOL_GPL(ping_init_sock);
dst_set_expires(&rt->dst, 0);
}
-static int ip_rt_bug(struct sk_buff *skb)
+static int ip_rt_bug(struct sock *sk, struct sk_buff *skb)
{
pr_debug("%s: %pI4 -> %pI4, %s\n",
__func__, &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr,
if (res.type == RTN_LOCAL) {
err = fib_validate_source(skb, saddr, daddr, tos,
- LOOPBACK_IFINDEX,
- dev, in_dev, &itag);
+ 0, dev, in_dev, &itag);
if (err < 0)
goto martian_source_keep_err;
goto local_input;
new->__use = 1;
new->input = dst_discard;
- new->output = dst_discard;
+ new->output = dst_discard_sk;
new->dev = ort->dst.dev;
if (new->dev)
}
} else
#endif
- if (nla_put_u32(skb, RTA_IIF, rt->rt_iif))
+ if (nla_put_u32(skb, RTA_IIF, skb->dev->ifindex))
goto nla_put_failure;
}
TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS,
tcp_skb_pcount(skb));
- err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl);
+ err = icsk->icsk_af_ops->queue_xmit(sk, skb, &inet->cork.fl);
if (likely(err <= 0))
return err;
return xfrm_output(skb);
}
-int xfrm4_output(struct sk_buff *skb)
+int xfrm4_output(struct sock *sk, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
struct xfrm_state *x = dst->xfrm;
return dst;
}
-int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused)
+int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused)
{
- struct sock *sk = skb->sk;
struct ipv6_pinfo *np = inet6_sk(sk);
struct flowi6 fl6;
struct dst_entry *dst;
return 0;
}
+static void ip6gre_dellink(struct net_device *dev, struct list_head *head)
+{
+ struct net *net = dev_net(dev);
+ struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
+
+ if (dev != ign->fb_tunnel_dev)
+ unregister_netdevice_queue(dev, head);
+}
+
static size_t ip6gre_get_size(const struct net_device *dev)
{
return
.validate = ip6gre_tunnel_validate,
.newlink = ip6gre_newlink,
.changelink = ip6gre_changelink,
+ .dellink = ip6gre_dellink,
.get_size = ip6gre_get_size,
.fill_info = ip6gre_fill_info,
};
return ip6_finish_output2(skb);
}
-int ip6_output(struct sk_buff *skb)
+int ip6_output(struct sock *sk, struct sk_buff *skb)
{
struct net_device *dev = skb_dst(skb)->dev;
struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
int err = 0;
struct ip6_tnl_parm p;
struct __ip6_tnl_parm p1;
- struct ip6_tnl *t = NULL;
- struct net *net = dev_net(dev);
+ struct ip6_tnl *t = netdev_priv(dev);
+ struct net *net = t->net;
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
switch (cmd) {
}
ip6_tnl_parm_from_user(&p1, &p);
t = ip6_tnl_locate(net, &p1, 0);
+ if (t == NULL)
+ t = netdev_priv(dev);
} else {
memset(&p, 0, sizeof(p));
}
- if (t == NULL)
- t = netdev_priv(dev);
ip6_tnl_parm_to_user(&p, &t->parms);
if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) {
err = -EFAULT;
struct mr6_table *mrt;
struct flowi6 fl6 = {
.flowi6_oif = dev->ifindex,
- .flowi6_iif = skb->skb_iif,
+ .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX,
.flowi6_mark = skb->mark,
};
int err;
static int ip6_dst_gc(struct dst_ops *ops);
static int ip6_pkt_discard(struct sk_buff *skb);
-static int ip6_pkt_discard_out(struct sk_buff *skb);
+static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb);
static int ip6_pkt_prohibit(struct sk_buff *skb);
-static int ip6_pkt_prohibit_out(struct sk_buff *skb);
+static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb);
static void ip6_link_failure(struct sk_buff *skb);
static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
struct sk_buff *skb, u32 mtu);
.obsolete = DST_OBSOLETE_FORCE_CHK,
.error = -EINVAL,
.input = dst_discard,
- .output = dst_discard,
+ .output = dst_discard_sk,
},
.rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
.rt6i_protocol = RTPROT_KERNEL,
new->__use = 1;
new->input = dst_discard;
- new->output = dst_discard;
+ new->output = dst_discard_sk;
if (dst_metrics_read_only(&ort->dst))
new->_metrics = ort->dst._metrics;
unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
if (mtu)
- return mtu;
+ goto out;
mtu = IPV6_MIN_MTU;
mtu = idev->cnf.mtu6;
rcu_read_unlock();
- return mtu;
+out:
+ return min_t(unsigned int, mtu, IP6_MAX_MTU);
}
static struct dst_entry *icmp6_dst_gc_list;
switch (cfg->fc_type) {
case RTN_BLACKHOLE:
rt->dst.error = -EINVAL;
- rt->dst.output = dst_discard;
+ rt->dst.output = dst_discard_sk;
rt->dst.input = dst_discard;
break;
case RTN_PROHIBIT:
return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES);
}
-static int ip6_pkt_discard_out(struct sk_buff *skb)
+static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb)
{
skb->dev = skb_dst(skb)->dev;
return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES);
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES);
}
-static int ip6_pkt_prohibit_out(struct sk_buff *skb)
+static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb)
{
skb->dev = skb_dst(skb)->dev;
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
goto out;
}
- err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos,
- ttl, df, !net_eq(tunnel->net, dev_net(dev)));
+ err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr,
+ IPPROTO_IPV6, tos, ttl, df,
+ !net_eq(tunnel->net, dev_net(dev)));
iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
return NETDEV_TX_OK;
int err = 0;
struct ip_tunnel_parm p;
struct ip_tunnel_prl prl;
- struct ip_tunnel *t;
- struct net *net = dev_net(dev);
+ struct ip_tunnel *t = netdev_priv(dev);
+ struct net *net = t->net;
struct sit_net *sitn = net_generic(net, sit_net_id);
#ifdef CONFIG_IPV6_SIT_6RD
struct ip_tunnel_6rd ip6rd;
#ifdef CONFIG_IPV6_SIT_6RD
case SIOCGET6RD:
#endif
- t = NULL;
if (dev == sitn->fb_tunnel_dev) {
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
err = -EFAULT;
break;
}
t = ipip6_tunnel_locate(net, &p, 0);
+ if (t == NULL)
+ t = netdev_priv(dev);
}
- if (t == NULL)
- t = netdev_priv(dev);
err = -EFAULT;
if (cmd == SIOCGETTUNNEL) {
err = -EINVAL;
if (dev == sitn->fb_tunnel_dev)
goto done;
- err = -ENOENT;
- if (!(t = netdev_priv(dev)))
- goto done;
err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data);
break;
err = -EFAULT;
if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl)))
goto done;
- err = -ENOENT;
- if (!(t = netdev_priv(dev)))
- goto done;
switch (cmd) {
case SIOCDELPRL:
sizeof(ip6rd)))
goto done;
- t = netdev_priv(dev);
-
if (cmd != SIOCDEL6RD) {
err = ipip6_tunnel_update_6rd(t, &ip6rd);
if (err < 0)
return x->outer_mode->afinfo->output_finish(skb);
}
-int xfrm6_output(struct sk_buff *skb)
+int xfrm6_output(struct sock *sk, struct sk_buff *skb)
{
return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL,
skb_dst(skb)->dev, __xfrm6_output);
skb->local_df = 1;
#if IS_ENABLED(CONFIG_IPV6)
if (tunnel->sock->sk_family == PF_INET6 && !tunnel->v4mapped)
- error = inet6_csk_xmit(skb, NULL);
+ error = inet6_csk_xmit(tunnel->sock, skb, NULL);
else
#endif
- error = ip_queue_xmit(skb, fl);
+ error = ip_queue_xmit(tunnel->sock, skb, fl);
/* Update stats */
if (error >= 0) {
xmit:
/* Queue the packet to IP for output */
- rc = ip_queue_xmit(skb, &inet->cork.fl);
+ rc = ip_queue_xmit(sk, skb, &inet->cork.fl);
rcu_read_unlock();
error:
if (!local->use_chanctx) {
local->_oper_chandef = *chandef;
- ieee80211_hw_config(local, 0);
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
} else {
err = drv_add_chanctx(local, ctx);
if (err) {
check_single_channel = true;
local->hw.conf.radar_enabled = false;
- ieee80211_hw_config(local, 0);
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
} else {
drv_remove_chanctx(local, ctx);
}
rx_chains_static = max(rx_chains_static, needed_static);
rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic);
}
+
+ /* Disable SMPS for the monitor interface */
+ sdata = rcu_dereference(local->monitor_sdata);
+ if (sdata &&
+ rcu_access_pointer(sdata->vif.chanctx_conf) == &chanctx->conf)
+ rx_chains_dynamic = rx_chains_static = local->rx_chains;
+
rcu_read_unlock();
if (!local->use_chanctx) {
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
if (!rcu_access_pointer(sdata->vif.chanctx_conf))
continue;
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ continue;
power = min(power, sdata->vif.bss_conf.txpower);
}
rcu_read_unlock();
{
struct ieee80211_local *local = sdata->local;
- if (!changed)
+ if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
return;
drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed);
struct ieee80211_roc_work *dep;
/* start this ROC */
+ ieee80211_offchannel_stop_vifs(local);
/* switch channel etc */
ieee80211_recalc_idle(local);
sta, true, acked);
if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) &&
+ (ieee80211_is_data(hdr->frame_control)) &&
(rates_idx != -1))
sta->last_tx_rate = info->status.rates[rates_idx];
int cpu;
atomic_set(&net->ct.count, 0);
+ seqcount_init(&net->ct.generation);
net->ct.pcpu_lists = alloc_percpu(struct ct_pcpu);
if (!net->ct.pcpu_lists)
.expect_policy = &pptp_exp_policy,
};
-static void nf_conntrack_pptp_net_exit(struct net *net)
-{
- nf_ct_gre_keymap_flush(net);
-}
-
-static struct pernet_operations nf_conntrack_pptp_net_ops = {
- .exit = nf_conntrack_pptp_net_exit,
-};
-
static int __init nf_conntrack_pptp_init(void)
{
- int rv;
-
- rv = nf_conntrack_helper_register(&pptp);
- if (rv < 0)
- return rv;
- rv = register_pernet_subsys(&nf_conntrack_pptp_net_ops);
- if (rv < 0)
- nf_conntrack_helper_unregister(&pptp);
- return rv;
+ return nf_conntrack_helper_register(&pptp);
}
static void __exit nf_conntrack_pptp_fini(void)
{
nf_conntrack_helper_unregister(&pptp);
- unregister_pernet_subsys(&nf_conntrack_pptp_net_ops);
}
module_init(nf_conntrack_pptp_init);
return net_generic(net, proto_gre_net_id);
}
-void nf_ct_gre_keymap_flush(struct net *net)
+static void nf_ct_gre_keymap_flush(struct net *net)
{
struct netns_proto_gre *net_gre = gre_pernet(net);
struct nf_ct_gre_keymap *km, *tmp;
}
write_unlock_bh(&net_gre->keymap_lock);
}
-EXPORT_SYMBOL(nf_ct_gre_keymap_flush);
static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km,
const struct nf_conntrack_tuple *t)
struct nft_data data[NFT_REG_MAX + 1])
{
const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr);
- u32 mask;
+ u32 mask = nft_cmp_fast_mask(priv->len);
- mask = ~0U >> (sizeof(priv->data) * BITS_PER_BYTE - priv->len);
if ((data[priv->sreg].data[0] & mask) == priv->data)
return;
data[NFT_REG_VERDICT].verdict = NFT_BREAK;
BUG_ON(err < 0);
desc.len *= BITS_PER_BYTE;
- mask = ~0U >> (sizeof(priv->data) * BITS_PER_BYTE - desc.len);
+ mask = nft_cmp_fast_mask(desc.len);
priv->data = data.data[0] & mask;
priv->len = desc.len;
return 0;
skb->local_df = 1;
- return iptunnel_xmit(rt, skb, fl.saddr,
+ return iptunnel_xmit(skb->sk, rt, skb, fl.saddr,
OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE,
OVS_CB(skb)->tun_key->ipv4_tos,
OVS_CB(skb)->tun_key->ipv4_ttl, df, false);
return false;
}
-/* Update asoc's rwnd for the approximated state in the buffer,
- * and check whether SACK needs to be sent.
- */
-void sctp_assoc_rwnd_update(struct sctp_association *asoc, bool update_peer)
+/* Increase asoc's rwnd by len and send any window update SACK if needed. */
+void sctp_assoc_rwnd_increase(struct sctp_association *asoc, unsigned int len)
{
- int rx_count;
struct sctp_chunk *sack;
struct timer_list *timer;
- if (asoc->ep->rcvbuf_policy)
- rx_count = atomic_read(&asoc->rmem_alloc);
- else
- rx_count = atomic_read(&asoc->base.sk->sk_rmem_alloc);
+ if (asoc->rwnd_over) {
+ if (asoc->rwnd_over >= len) {
+ asoc->rwnd_over -= len;
+ } else {
+ asoc->rwnd += (len - asoc->rwnd_over);
+ asoc->rwnd_over = 0;
+ }
+ } else {
+ asoc->rwnd += len;
+ }
- if ((asoc->base.sk->sk_rcvbuf - rx_count) > 0)
- asoc->rwnd = (asoc->base.sk->sk_rcvbuf - rx_count) >> 1;
- else
- asoc->rwnd = 0;
+ /* If we had window pressure, start recovering it
+ * once our rwnd had reached the accumulated pressure
+ * threshold. The idea is to recover slowly, but up
+ * to the initial advertised window.
+ */
+ if (asoc->rwnd_press && asoc->rwnd >= asoc->rwnd_press) {
+ int change = min(asoc->pathmtu, asoc->rwnd_press);
+ asoc->rwnd += change;
+ asoc->rwnd_press -= change;
+ }
- pr_debug("%s: asoc:%p rwnd=%u, rx_count=%d, sk_rcvbuf=%d\n",
- __func__, asoc, asoc->rwnd, rx_count,
- asoc->base.sk->sk_rcvbuf);
+ pr_debug("%s: asoc:%p rwnd increased by %d to (%u, %u) - %u\n",
+ __func__, asoc, len, asoc->rwnd, asoc->rwnd_over,
+ asoc->a_rwnd);
/* Send a window update SACK if the rwnd has increased by at least the
* minimum of the association's PMTU and half of the receive buffer.
* The algorithm used is similar to the one described in
* Section 4.2.3.3 of RFC 1122.
*/
- if (update_peer && sctp_peer_needs_update(asoc)) {
+ if (sctp_peer_needs_update(asoc)) {
asoc->a_rwnd = asoc->rwnd;
pr_debug("%s: sending window update SACK- asoc:%p rwnd:%u "
}
}
+/* Decrease asoc's rwnd by len. */
+void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned int len)
+{
+ int rx_count;
+ int over = 0;
+
+ if (unlikely(!asoc->rwnd || asoc->rwnd_over))
+ pr_debug("%s: association:%p has asoc->rwnd:%u, "
+ "asoc->rwnd_over:%u!\n", __func__, asoc,
+ asoc->rwnd, asoc->rwnd_over);
+
+ if (asoc->ep->rcvbuf_policy)
+ rx_count = atomic_read(&asoc->rmem_alloc);
+ else
+ rx_count = atomic_read(&asoc->base.sk->sk_rmem_alloc);
+
+ /* If we've reached or overflowed our receive buffer, announce
+ * a 0 rwnd if rwnd would still be positive. Store the
+ * the potential pressure overflow so that the window can be restored
+ * back to original value.
+ */
+ if (rx_count >= asoc->base.sk->sk_rcvbuf)
+ over = 1;
+
+ if (asoc->rwnd >= len) {
+ asoc->rwnd -= len;
+ if (over) {
+ asoc->rwnd_press += asoc->rwnd;
+ asoc->rwnd = 0;
+ }
+ } else {
+ asoc->rwnd_over = len - asoc->rwnd;
+ asoc->rwnd = 0;
+ }
+
+ pr_debug("%s: asoc:%p rwnd decreased by %d to (%u, %u, %u)\n",
+ __func__, asoc, len, asoc->rwnd, asoc->rwnd_over,
+ asoc->rwnd_press);
+}
/* Build the bind address list for the association based on info from the
* local endpoint and the remote peer.
*/
int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
{
- struct net *net = sock_net(asoc->base.sk);
struct sctp_auth_bytes *secret;
struct sctp_shared_key *ep_key;
/* If we don't support AUTH, or peer is not capable
* we don't need to do anything.
*/
- if (!net->sctp.auth_enable || !asoc->peer.auth_capable)
+ if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)
return 0;
/* If the key_id is non-zero and we couldn't find an
*/
int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp)
{
- struct net *net = sock_net(ep->base.sk);
struct crypto_hash *tfm = NULL;
__u16 id;
- /* if the transforms are already allocted, we are done */
- if (!net->sctp.auth_enable) {
+ /* If AUTH extension is disabled, we are done */
+ if (!ep->auth_enable) {
ep->auth_hmacs = NULL;
return 0;
}
+ /* If the transforms are already allocated, we are done */
if (ep->auth_hmacs)
return 0;
/* Check if peer requested that this chunk is authenticated */
int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
{
- struct net *net;
if (!asoc)
return 0;
- net = sock_net(asoc->base.sk);
- if (!net->sctp.auth_enable || !asoc->peer.auth_capable)
+ if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)
return 0;
return __sctp_auth_cid(chunk, asoc->peer.peer_chunks);
/* Check if we requested that peer authenticate this chunk. */
int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
{
- struct net *net;
if (!asoc)
return 0;
- net = sock_net(asoc->base.sk);
- if (!net->sctp.auth_enable)
+ if (!asoc->ep->auth_enable)
return 0;
return __sctp_auth_cid(chunk,
if (!ep->digest)
return NULL;
- if (net->sctp.auth_enable) {
+ ep->auth_enable = net->sctp.auth_enable;
+ if (ep->auth_enable) {
/* Allocate space for HMACS and CHUNKS authentication
* variables. There are arrays that we encode directly
* into parameters to make the rest of the operations easier.
SCTP_INC_STATS(sock_net(&inet->sk), SCTP_MIB_OUTSCTPPACKS);
- return ip_queue_xmit(skb, &transport->fl);
+ return ip_queue_xmit(&inet->sk, skb, &transport->fl);
}
static struct sctp_af sctp_af_inet;
gfp_t gfp, int vparam_len)
{
struct net *net = sock_net(asoc->base.sk);
+ struct sctp_endpoint *ep = asoc->ep;
sctp_inithdr_t init;
union sctp_params addrs;
size_t chunksize;
chunksize += vparam_len;
/* Account for AUTH related parameters */
- if (net->sctp.auth_enable) {
+ if (ep->auth_enable) {
/* Add random parameter length*/
chunksize += sizeof(asoc->c.auth_random);
}
/* Add SCTP-AUTH chunks to the parameter list */
- if (net->sctp.auth_enable) {
+ if (ep->auth_enable) {
sctp_addto_chunk(retval, sizeof(asoc->c.auth_random),
asoc->c.auth_random);
if (auth_hmacs)
/* if the peer reports AUTH, assume that he
* supports AUTH.
*/
- if (net->sctp.auth_enable)
+ if (asoc->ep->auth_enable)
asoc->peer.auth_capable = 1;
break;
case SCTP_CID_ASCONF:
* SCTP_IERROR_NO_ERROR - continue with the chunk
*/
static sctp_ierror_t sctp_verify_param(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
union sctp_params param,
sctp_cid_t cid,
goto fallthrough;
case SCTP_PARAM_RANDOM:
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
goto fallthrough;
/* SCTP-AUTH: Secion 6.1
break;
case SCTP_PARAM_CHUNKS:
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
goto fallthrough;
/* SCTP-AUTH: Section 3.2
break;
case SCTP_PARAM_HMAC_ALGO:
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
goto fallthrough;
hmacs = (struct sctp_hmac_algo_param *)param.p;
}
/* Verify the INIT packet before we process it. */
-int sctp_verify_init(struct net *net, const struct sctp_association *asoc,
- sctp_cid_t cid,
- sctp_init_chunk_t *peer_init,
- struct sctp_chunk *chunk,
+int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep,
+ const struct sctp_association *asoc, sctp_cid_t cid,
+ sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk,
struct sctp_chunk **errp)
{
union sctp_params param;
/* Verify all the variable length parameters */
sctp_walk_params(param, peer_init, init_hdr.params) {
-
- result = sctp_verify_param(net, asoc, param, cid, chunk, errp);
+ result = sctp_verify_param(net, ep, asoc, param, cid,
+ chunk, errp);
switch (result) {
case SCTP_IERROR_ABORT:
case SCTP_IERROR_NOMEM:
struct sctp_af *af;
union sctp_addr_param *addr_param;
struct sctp_transport *t;
+ struct sctp_endpoint *ep = asoc->ep;
/* We maintain all INIT parameters in network byte order all the
* time. This allows us to not worry about whether the parameters
goto fall_through;
case SCTP_PARAM_RANDOM:
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
goto fall_through;
/* Save peer's random parameter */
break;
case SCTP_PARAM_HMAC_ALGO:
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
goto fall_through;
/* Save peer's HMAC list */
break;
case SCTP_PARAM_CHUNKS:
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
goto fall_through;
asoc->peer.peer_chunks = kmemdup(param.p,
/* Verify the INIT chunk before processing it. */
err_chunk = NULL;
- if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type,
+ if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
(sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
&err_chunk)) {
/* This chunk contains fatal error. It is to be discarded.
/* Verify the INIT chunk before processing it. */
err_chunk = NULL;
- if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type,
+ if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
(sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
&err_chunk)) {
/* Verify the INIT chunk before processing it. */
err_chunk = NULL;
- if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type,
+ if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
(sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
&err_chunk)) {
/* This chunk contains fatal error. It is to be discarded.
* PMTU. In cases, such as loopback, this might be a rather
* large spill over.
*/
- if ((!chunk->data_accepted) && (!asoc->rwnd ||
+ if ((!chunk->data_accepted) && (!asoc->rwnd || asoc->rwnd_over ||
(datalen > asoc->rwnd + asoc->frag_point))) {
/* If this is the next TSN, consider reneging to make
sctp_skb_pull(skb, copied);
skb_queue_head(&sk->sk_receive_queue, skb);
+ /* When only partial message is copied to the user, increase
+ * rwnd by that amount. If all the data in the skb is read,
+ * rwnd is updated when the event is freed.
+ */
+ if (!sctp_ulpevent_is_notification(event))
+ sctp_assoc_rwnd_increase(event->asoc, copied);
goto out;
} else if ((event->msg_flags & MSG_NOTIFICATION) ||
(event->msg_flags & MSG_EOR))
char __user *optval,
unsigned int optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authchunk val;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (optlen != sizeof(struct sctp_authchunk))
}
/* add this chunk id to the endpoint */
- return sctp_auth_ep_add_chunkid(sctp_sk(sk)->ep, val.sauth_chunk);
+ return sctp_auth_ep_add_chunkid(ep, val.sauth_chunk);
}
/*
char __user *optval,
unsigned int optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_hmacalgo *hmacs;
u32 idents;
int err;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (optlen < sizeof(struct sctp_hmacalgo))
goto out;
}
- err = sctp_auth_ep_set_hmacs(sctp_sk(sk)->ep, hmacs);
+ err = sctp_auth_ep_set_hmacs(ep, hmacs);
out:
kfree(hmacs);
return err;
char __user *optval,
unsigned int optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authkey *authkey;
struct sctp_association *asoc;
int ret;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (optlen <= sizeof(struct sctp_authkey))
goto out;
}
- ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey);
+ ret = sctp_auth_set_key(ep, asoc, authkey);
out:
kzfree(authkey);
return ret;
char __user *optval,
unsigned int optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authkeyid val;
struct sctp_association *asoc;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (optlen != sizeof(struct sctp_authkeyid))
if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
return -EINVAL;
- return sctp_auth_set_active_key(sctp_sk(sk)->ep, asoc,
- val.scact_keynumber);
+ return sctp_auth_set_active_key(ep, asoc, val.scact_keynumber);
}
/*
char __user *optval,
unsigned int optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authkeyid val;
struct sctp_association *asoc;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (optlen != sizeof(struct sctp_authkeyid))
if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
return -EINVAL;
- return sctp_auth_del_key_id(sctp_sk(sk)->ep, asoc,
- val.scact_keynumber);
+ return sctp_auth_del_key_id(ep, asoc, val.scact_keynumber);
}
static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
char __user *optval, int __user *optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_hmacalgo __user *p = (void __user *)optval;
struct sctp_hmac_algo_param *hmacs;
__u16 data_len = 0;
u32 num_idents;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
- hmacs = sctp_sk(sk)->ep->auth_hmacs_list;
+ hmacs = ep->auth_hmacs_list;
data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t);
if (len < sizeof(struct sctp_hmacalgo) + data_len)
static int sctp_getsockopt_active_key(struct sock *sk, int len,
char __user *optval, int __user *optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authkeyid val;
struct sctp_association *asoc;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (len < sizeof(struct sctp_authkeyid))
if (asoc)
val.scact_keynumber = asoc->active_key_id;
else
- val.scact_keynumber = sctp_sk(sk)->ep->active_key_id;
+ val.scact_keynumber = ep->active_key_id;
len = sizeof(struct sctp_authkeyid);
if (put_user(len, optlen))
static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
char __user *optval, int __user *optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authchunks __user *p = (void __user *)optval;
struct sctp_authchunks val;
struct sctp_association *asoc;
u32 num_chunks = 0;
char __user *to;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (len < sizeof(struct sctp_authchunks))
static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
char __user *optval, int __user *optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authchunks __user *p = (void __user *)optval;
struct sctp_authchunks val;
struct sctp_association *asoc;
u32 num_chunks = 0;
char __user *to;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (len < sizeof(struct sctp_authchunks))
if (asoc)
ch = (struct sctp_chunks_param *)asoc->c.auth_chunks;
else
- ch = sctp_sk(sk)->ep->auth_chunk_list;
+ ch = ep->auth_chunk_list;
if (!ch)
goto num;
static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos);
+static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos);
static struct ctl_table sctp_table[] = {
{
.data = &init_net.sctp.auth_enable,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec,
+ .proc_handler = proc_sctp_do_auth,
},
{
.procname = "addr_scope_policy",
return ret;
}
+static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos)
+{
+ struct net *net = current->nsproxy->net_ns;
+ struct ctl_table tbl;
+ int new_value, ret;
+
+ memset(&tbl, 0, sizeof(struct ctl_table));
+ tbl.maxlen = sizeof(unsigned int);
+
+ if (write)
+ tbl.data = &new_value;
+ else
+ tbl.data = &net->sctp.auth_enable;
+
+ ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
+
+ if (write) {
+ struct sock *sk = net->sctp.ctl_sock;
+
+ net->sctp.auth_enable = new_value;
+ /* Update the value in the control socket */
+ lock_sock(sk);
+ sctp_sk(sk)->ep->auth_enable = new_value;
+ release_sock(sk);
+ }
+
+ return ret;
+}
+
int sctp_sysctl_net_register(struct net *net)
{
struct ctl_table *table = sctp_net_table;
skb = sctp_event2skb(event);
/* Set the owner and charge rwnd for bytes received. */
sctp_ulpevent_set_owner(event, asoc);
- sctp_assoc_rwnd_update(asoc, false);
+ sctp_assoc_rwnd_decrease(asoc, skb_headlen(skb));
if (!skb->data_len)
return;
{
struct sk_buff *skb, *frag;
unsigned int len;
- struct sctp_association *asoc;
/* Current stack structures assume that the rcv buffer is
* per socket. For UDP style sockets this is not true as
}
done:
- asoc = event->asoc;
- sctp_association_hold(asoc);
+ sctp_assoc_rwnd_increase(event->asoc, len);
sctp_ulpevent_release_owner(event);
- sctp_assoc_rwnd_update(asoc, true);
- sctp_association_put(asoc);
}
static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event)
* Receive a datagram from a socket.
*/
-asmlinkage long sys_recv(int fd, void __user *ubuf, size_t size,
- unsigned int flags)
+SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
+ unsigned int, flags)
{
return sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
}
xfrm_pol_put(pol);
}
-static int xdst_queue_output(struct sk_buff *skb)
+static int xdst_queue_output(struct sock *sk, struct sk_buff *skb)
{
unsigned long sched_next;
struct dst_entry *dst = skb_dst(skb);
case F_GETLK:
case F_SETLK:
case F_SETLKW:
- case F_GETLKP:
- case F_SETLKP:
- case F_SETLKPW:
+ case F_OFD_GETLK:
+ case F_OFD_SETLK:
+ case F_OFD_SETLKW:
#if BITS_PER_LONG == 32
case F_GETLK64:
case F_SETLK64:
snd_es18xx_mixer_write(chip, 0x78, 0x93);
#ifdef AVOID_POPS
/* Avoid pops */
- udelay(100000);
+ mdelay(100);
if (chip->caps & ES18XX_PCM2)
/* Restore Audio 2 volume */
snd_es18xx_mixer_write(chip, 0x7C, chip->audio2_vol);
/* Stop DMA */
snd_es18xx_mixer_write(chip, 0x78, 0x00);
#ifdef AVOID_POPS
- udelay(25000);
+ mdelay(25);
if (chip->caps & ES18XX_PCM2)
/* Set Audio 2 volume to 0 */
snd_es18xx_mixer_write(chip, 0x7C, 0);
snd_es18xx_write(chip, 0xA5, count >> 8);
#ifdef AVOID_POPS
- udelay(100000);
+ mdelay(100);
#endif
/* Set format */
snd_es18xx_write(chip, 0xB8, 0x05);
#ifdef AVOID_POPS
/* Avoid pops */
- udelay(100000);
+ mdelay(100);
/* Enable Audio 1 */
snd_es18xx_dsp_command(chip, 0xD1);
#endif
snd_es18xx_write(chip, 0xB8, 0x00);
#ifdef AVOID_POPS
/* Avoid pops */
- udelay(25000);
+ mdelay(25);
/* Disable Audio 1 */
snd_es18xx_dsp_command(chip, 0xD3);
#endif
SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
spec->codec_variant = ALC269_TYPE_ALC285;
break;
case 0x10ec0286:
+ case 0x10ec0288:
spec->codec_variant = ALC269_TYPE_ALC286;
break;
case 0x10ec0255:
SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE),
SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE),
+ SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
{ .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 },
{ .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 },
{ .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 },
+ { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 },
{ .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
{ .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
{ .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 },
if (!access(target_fname, F_OK)) {
syslog(LOG_INFO, "File: %s exists", target_fname);
- if (!smsg->copy_flags & OVER_WRITE)
+ if (!(smsg->copy_flags & OVER_WRITE)) {
+ error = HV_ERROR_ALREADY_EXISTS;
goto done;
+ }
}
target_fd = open(target_fname, O_RDWR | O_CREAT | O_CLOEXEC, 0744);
-# liblockdep version
-LL_VERSION = 0
-LL_PATCHLEVEL = 0
-LL_EXTRAVERSION = 1
-
# file format version
FILE_VERSION = 1
MAKEFLAGS += --no-print-directory
-
+LIBLOCKDEP_VERSION=$(shell make -sC ../../.. kernelversion)
# Makefiles suck: This macro sets a default value of $(2) for the
# variable named by $(1), unless the variable has been set by
libdir_SQ = $(subst ','\'',$(libdir))
bindir_SQ = $(subst ','\'',$(bindir))
-LIB_FILE = liblockdep.a liblockdep.so
+LIB_FILE = liblockdep.a liblockdep.so.$(LIBLOCKDEP_VERSION)
BIN_FILE = lockdep
CONFIG_INCLUDES =
export Q VERBOSE
-LIBLOCKDEP_VERSION = $(LL_VERSION).$(LL_PATCHLEVEL).$(LL_EXTRAVERSION)
-
INCLUDES = -I. -I/usr/local/include -I./uinclude -I./include $(CONFIG_INCLUDES)
# Set compile option CFLAGS if not set elsewhere
do_compile_shared_library = \
($(print_shared_lib_compile) \
- $(CC) --shared $^ -o $@ -lpthread -ldl)
+ $(CC) --shared $^ -o $@ -lpthread -ldl -Wl,-soname='"$@"';$(shell ln -s $@ liblockdep.so))
do_build_static_lib = \
($(print_static_lib_build) \
all_cmd: $(CMD_TARGETS)
-liblockdep.so: $(PEVENT_LIB_OBJS)
+liblockdep.so.$(LIBLOCKDEP_VERSION): $(PEVENT_LIB_OBJS)
$(Q)$(do_compile_shared_library)
liblockdep.a: $(PEVENT_LIB_OBJS)
#define MAX_LOCK_DEPTH 2000UL
+#define asmlinkage
+#define __visible
+
#include "../../../include/linux/lockdep.h"
struct task_struct {
warning(fmt, ##__VA_ARGS__); \
} while (0)
+#define do_warning_event(event, fmt, ...) \
+ do { \
+ if (!show_warning) \
+ continue; \
+ \
+ if (event) \
+ warning("[%s:%s] " fmt, event->system, \
+ event->name, ##__VA_ARGS__); \
+ else \
+ warning(fmt, ##__VA_ARGS__); \
+ } while (0)
+
static void init_input_buf(const char *buf, unsigned long long size)
{
input_buf = buf;
}
if (!field->type) {
- do_warning("%s: no type found", __func__);
+ do_warning_event(event, "%s: no type found", __func__);
goto fail;
}
field->name = last_token;
free_token(token);
type = read_token(&token);
if (type == EVENT_NONE) {
- do_warning("failed to find token");
+ do_warning_event(event, "failed to find token");
goto fail;
}
}
right = alloc_arg();
if (!arg || !left || !right) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
/* arg will be freed at out_free */
free_arg(left);
free_arg(right);
arg = alloc_arg();
if (!arg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
/* '*tok' is set to top->op.op. No need to free. */
*tok = NULL;
return EVENT_ERROR;
if (arg->type == PRINT_OP && !arg->op.left) {
/* handle single op */
if (token[1]) {
- do_warning("bad op token %s", token);
+ do_warning_event(event, "bad op token %s", token);
goto out_free;
}
switch (token[0]) {
case '-':
break;
default:
- do_warning("bad op token %s", token);
+ do_warning_event(event, "bad op token %s", token);
goto out_free;
}
char *new_atom;
if (left->type != PRINT_ATOM) {
- do_warning("bad pointer type");
+ do_warning_event(event, "bad pointer type");
goto out_free;
}
new_atom = realloc(left->atom.atom,
type = process_array(event, arg, tok);
} else {
- do_warning("unknown op '%s'", token);
+ do_warning_event(event, "unknown op '%s'", token);
event->flags |= EVENT_FL_FAILED;
/* the arg is now the left side */
goto out_free;
return type;
out_warn_free:
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
out_free:
free_token(token);
*tok = NULL;
field = alloc_arg();
if (!field) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
goto out_free;
}
field = alloc_arg();
if (!field) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
goto out_free;
}
field = alloc_arg();
if (!field) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
goto out_free;
}
field = alloc_arg();
if (!field) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
*tok = NULL;
return EVENT_ERROR;
}
free_token(token);
arg = alloc_arg();
if (!arg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
*tok = NULL;
return EVENT_ERROR;
}
/* prevous must be an atom */
if (arg->type != PRINT_ATOM) {
- do_warning("previous needed to be PRINT_ATOM");
+ do_warning_event(event, "previous needed to be PRINT_ATOM");
goto out_free;
}
item_arg = alloc_arg();
if (!item_arg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!",
+ __func__);
goto out_free;
}
for (i = 0; i < func->nr_args; i++) {
farg = alloc_arg();
if (!farg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!",
+ __func__);
return EVENT_ERROR;
}
type = process_arg(event, farg, &token);
if (i < (func->nr_args - 1)) {
if (type != EVENT_DELIM || strcmp(token, ",") != 0) {
- warning("Error: function '%s()' expects %d arguments but event %s only uses %d",
+ do_warning_event(event,
+ "Error: function '%s()' expects %d arguments but event %s only uses %d",
func->name, func->nr_args,
event->name, i + 1);
goto err;
}
} else {
if (type != EVENT_DELIM || strcmp(token, ")") != 0) {
- warning("Error: function '%s()' only expects %d arguments but event %s has more",
+ do_warning_event(event,
+ "Error: function '%s()' only expects %d arguments but event %s has more",
func->name, func->nr_args, event->name);
goto err;
}
return process_func_handler(event, func, arg, tok);
}
- do_warning("function %s not defined", token);
+ do_warning_event(event, "function %s not defined", token);
free_token(token);
return EVENT_ERROR;
}
case EVENT_ERROR ... EVENT_NEWLINE:
default:
- do_warning("unexpected type %d", type);
+ do_warning_event(event, "unexpected type %d", type);
return EVENT_ERROR;
}
*tok = token;
arg = alloc_arg();
if (!arg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!",
+ __func__);
return -1;
}
return val;
out_warning_op:
- do_warning("%s: unknown op '%s'", __func__, arg->op.op);
+ do_warning_event(event, "%s: unknown op '%s'", __func__, arg->op.op);
return 0;
out_warning_field:
- do_warning("%s: field %s not found", __func__, arg->field.name);
+ do_warning_event(event, "%s: field %s not found",
+ __func__, arg->field.name);
return 0;
}
}
str = malloc(len + 1);
if (!str) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!",
+ __func__);
return;
}
memcpy(str, data + field->offset, len);
return;
out_warning_field:
- do_warning("%s: field %s not found", __func__, arg->field.name);
+ do_warning_event(event, "%s: field %s not found",
+ __func__, arg->field.name);
}
static unsigned long long
trace_seq_terminate(&str);
string = malloc(sizeof(*string));
if (!string) {
- do_warning("%s(%d): malloc str", __func__, __LINE__);
+ do_warning_event(event, "%s(%d): malloc str",
+ __func__, __LINE__);
goto out_free;
}
string->next = strings;
string->str = strdup(str.buffer);
if (!string->str) {
free(string);
- do_warning("%s(%d): malloc str", __func__, __LINE__);
+ do_warning_event(event, "%s(%d): malloc str",
+ __func__, __LINE__);
goto out_free;
}
args[i] = (uintptr_t)string->str;
* Something went totally wrong, this is not
* an input error, something in this code broke.
*/
- do_warning("Unexpected end of arguments\n");
+ do_warning_event(event, "Unexpected end of arguments\n");
goto out_free;
}
farg = farg->next;
if (!field) {
field = pevent_find_field(event, "buf");
if (!field) {
- do_warning("can't find buffer field for binary printk");
+ do_warning_event(event, "can't find buffer field for binary printk");
return NULL;
}
ip_field = pevent_find_field(event, "ip");
if (!ip_field) {
- do_warning("can't find ip field for binary printk");
+ do_warning_event(event, "can't find ip field for binary printk");
return NULL;
}
pevent->bprint_buf_field = field;
*/
args = alloc_arg();
if (!args) {
- do_warning("%s(%d): not enough memory!", __func__, __LINE__);
+ do_warning_event(event, "%s(%d): not enough memory!",
+ __func__, __LINE__);
return NULL;
}
arg = args;
bptr += vsize;
arg = alloc_arg();
if (!arg) {
- do_warning("%s(%d): not enough memory!",
+ do_warning_event(event, "%s(%d): not enough memory!",
__func__, __LINE__);
goto out_free;
}
case 's':
arg = alloc_arg();
if (!arg) {
- do_warning("%s(%d): not enough memory!",
+ do_warning_event(event, "%s(%d): not enough memory!",
__func__, __LINE__);
goto out_free;
}
if (!field) {
field = pevent_find_field(event, "fmt");
if (!field) {
- do_warning("can't find format field for binary printk");
+ do_warning_event(event, "can't find format field for binary printk");
return NULL;
}
pevent->bprint_fmt_field = field;
arg->field.field =
pevent_find_any_field(event, arg->field.name);
if (!arg->field.field) {
- do_warning("%s: field %s not found",
- __func__, arg->field.name);
+ do_warning_event(event, "%s: field %s not found",
+ __func__, arg->field.name);
return;
}
}
case '*':
/* The argument is the length. */
if (!arg) {
- do_warning("no argument match");
+ do_warning_event(event, "no argument match");
event->flags |= EVENT_FL_FAILED;
goto out_failed;
}
case 'X':
case 'u':
if (!arg) {
- do_warning("no argument match");
+ do_warning_event(event, "no argument match");
event->flags |= EVENT_FL_FAILED;
goto out_failed;
}
/* should never happen */
if (len > 31) {
- do_warning("bad format!");
+ do_warning_event(event, "bad format!");
event->flags |= EVENT_FL_FAILED;
len = 31;
}
trace_seq_printf(s, format, (long long)val);
break;
default:
- do_warning("bad count (%d)", ls);
+ do_warning_event(event, "bad count (%d)", ls);
event->flags |= EVENT_FL_FAILED;
}
break;
case 's':
if (!arg) {
- do_warning("no matching argument");
+ do_warning_event(event, "no matching argument");
event->flags |= EVENT_FL_FAILED;
goto out_failed;
}
/* should never happen */
if (len > 31) {
- do_warning("bad format!");
+ do_warning_event(event, "bad format!");
event->flags |= EVENT_FL_FAILED;
len = 31;
}
'mem'::
Memory access performance.
+'numa'::
+ NUMA scheduling and MM benchmarks.
+
+'futex'::
+ Futex stressing benchmarks.
+
'all'::
All benchmark subsystems.
--no-prefault::
Show only the result without page faults before memset.
+SUITES FOR 'numa'
+~~~~~~~~~~~~~~~~~
+*mem*::
+Suite for evaluating NUMA workloads.
+
+SUITES FOR 'futex'
+~~~~~~~~~~~~~~~~~~
+*hash*::
+Suite for evaluating hash tables.
+
+*wake*::
+Suite for evaluating wake calls.
+
+*requeue*::
+Suite for evaluating requeue calls.
+
SEE ALSO
--------
linkperf:perf[1]
--realtime=<priority>::
Collect data with this RT SCHED_FIFO priority.
--s <symbol>::
--sym-annotate=<symbol>::
Annotate this symbol.
export PERL_PATH
$(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c
- $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
+ $(QUIET_FLEX)$(FLEX) -o $@ --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) util/parse-events.l
$(OUTPUT)util/parse-events-bison.c: util/parse-events.y
$(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c -p parse_events_
$(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c
- $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
+ $(QUIET_FLEX)$(FLEX) -o $@ --header-file=$(OUTPUT)util/pmu-flex.h util/pmu.l
$(OUTPUT)util/pmu-bison.c: util/pmu.y
$(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c -p perf_pmu_
p->data_rand_walk = true;
p->nr_loops = -1;
p->init_random = true;
+ p->mb_global_str = "1";
+ p->nr_proc = 1;
+ p->nr_threads = 1;
+ p->nr_secs = 5;
p->run_all = argc == 1;
}
}
event->key = *key;
+ init_stats(&event->total.stats);
return event;
}
session = perf_session__new(file, false, NULL);
if (session == NULL) {
- pr_err("Not enough memory for reading perf file header\n");
+ pr_err("Perf session creation failed.\n");
return -1;
}
static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
{
- memset(evsel->priv, 0, sizeof(struct perf_stat));
+ int i;
+ struct perf_stat *ps = evsel->priv;
+
+ for (i = 0; i < 3; i++)
+ init_stats(&ps->res_stats[i]);
}
static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
{
evsel->priv = zalloc(sizeof(struct perf_stat));
- return evsel->priv == NULL ? -ENOMEM : 0;
+ if (evsel == NULL)
+ return -ENOMEM;
+ perf_evsel__reset_stat_priv(evsel);
+ return 0;
}
static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
ifdef LIBDW_DIR
LIBDW_CFLAGS := -I$(LIBDW_DIR)/include
LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
-
- FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS)
- FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw
endif
+ FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS)
+ FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw
endif
# include ARCH specific config
NO_LIBELF := 1
NO_DWARF := 1
NO_DEMANGLE := 1
+ NO_LIBUNWIND := 1
+ NO_LIBDW_DWARF_UNWIND := 1
else
msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
endif
if (ret < 0) {
if (!excl_kernel) {
excl_kernel = true;
+ perf_evlist__set_maps(evlist, NULL, NULL);
perf_evlist__delete(evlist);
evlist = NULL;
continue;
static int open_file_write(struct perf_data_file *file)
{
+ int fd;
+
if (check_backup(file))
return -1;
- return open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR);
+ fd = open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR);
+
+ if (fd < 0)
+ pr_err("failed to open %s : %s\n", file->path, strerror(errno));
+
+ return fd;
}
static int open_file(struct perf_data_file *file)
#if _ELFUTILS_PREREQ(0, 142)
/* Get the call frame information from this dwarf */
- pf->cfi = dwarf_getcfi(dbg->dbg);
+ pf->cfi = dwarf_getcfi_elf(dwarf_getelf(dbg->dbg));
#endif
off = 0;
void *data)
{
struct line_finder *lf = data;
+ int err;
if ((strtailcmp(fname, lf->fname) != 0) ||
(lf->lno_s > lineno || lf->lno_e < lineno))
return 0;
- if (line_range_add_line(fname, lineno, lf->lr) < 0)
- return -EINVAL;
+ err = line_range_add_line(fname, lineno, lf->lr);
+ if (err < 0 && err != -EEXIST)
+ return err;
return 0;
}
static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
{
- find_line_range_by_line(in_die, data);
+ int ret = find_line_range_by_line(in_die, data);
/*
* We have to check all instances of inlined function, because
* some execution paths can be optimized out depends on the
- * function argument of instances
+ * function argument of instances. However, if an error occurs,
+ * it should be handled by the caller.
*/
- return 0;
+ return ret < 0 ? ret : 0;
}
/* Search function definition from function name */
#include <inttypes.h>
#include "symbol.h"
+#include "vdso.h"
#include <symbol/kallsyms.h>
#include "debug.h"
GElf_Shdr shdr;
ss->adjust_symbols = (ehdr.e_type == ET_EXEC ||
ehdr.e_type == ET_REL ||
+ is_vdso_map(dso->short_name) ||
elf_section_by_name(elf, &ehdr, &shdr,
".gnu.prelink_undo",
NULL) != NULL);
STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment
endif
-# if DEBUG is enabled, then we do not strip or optimize
-ifeq ($(strip $(DEBUG)),true)
- CFLAGS += -O1 -g -DDEBUG
- STRIPCMD = /bin/true -Since_we_are_debugging
-else
- CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer
- STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment
-endif
-
# --- ACPIDUMP BEGIN ---
vpath %.c \
-rm -f $(OUTPUT)acpidump
install-tools:
- $(INSTALL) -d $(DESTDIR)${bindir}
+ $(INSTALL) -d $(DESTDIR)${sbindir}
$(INSTALL_PROGRAM) $(OUTPUT)acpidump $(DESTDIR)${sbindir}
install-man:
bitmap_zero(ioapic->rtc_status.dest_map, KVM_MAX_VCPUS);
}
+static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic);
+
+static void rtc_status_pending_eoi_check_valid(struct kvm_ioapic *ioapic)
+{
+ if (WARN_ON(ioapic->rtc_status.pending_eoi < 0))
+ kvm_rtc_eoi_tracking_restore_all(ioapic);
+}
+
static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
{
bool new_val, old_val;
} else {
__clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map);
ioapic->rtc_status.pending_eoi--;
+ rtc_status_pending_eoi_check_valid(ioapic);
}
-
- WARN_ON(ioapic->rtc_status.pending_eoi < 0);
}
void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
static void rtc_irq_eoi(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu)
{
- if (test_and_clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map))
+ if (test_and_clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map)) {
--ioapic->rtc_status.pending_eoi;
-
- WARN_ON(ioapic->rtc_status.pending_eoi < 0);
+ rtc_status_pending_eoi_check_valid(ioapic);
+ }
}
static bool rtc_irq_check_coalesced(struct kvm_ioapic *ioapic)
ioapic->irr &= ~(1 << irq);
if (irq == RTC_GSI && line_status) {
+ /*
+ * pending_eoi cannot ever become negative (see
+ * rtc_status_pending_eoi_check_valid) and the caller
+ * ensures that it is only called if it is >= zero, namely
+ * if rtc_irq_check_coalesced returns false).
+ */
BUG_ON(ioapic->rtc_status.pending_eoi != 0);
ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe,
ioapic->rtc_status.dest_map);
- ioapic->rtc_status.pending_eoi = ret;
+ ioapic->rtc_status.pending_eoi = (ret < 0 ? 0 : ret);
} else
ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, NULL);