In case IRQ configuration is unknown possibly enabled MSIs
are left enabled in ath10k_pci_deinit_irq(). This update
fixes the described misbehaviour.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
The documentation states that pci_enable_msi_block() returns the number of
requests 'could have been allocated', not 'could allocate'. IOW, MSIs are *not*
enabled if a positive value returned.
kvalo: add commit log based on Alexander's email
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Pass frames with invalid peer status to upper layer.
Next mac80211 will validate frames and drop if required.
This is required to detect spurious frames and pass
this info to user mode (detect CLASS2 CLASS3 frames from
nonauthenticated/nonassociated stations).
Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
If SMAP support is not compiled into the kernel, don't enable SMAP in
CR4 -- in fact, we should clear it, because the kernel doesn't contain
the proper STAC/CLAC instructions for SMAP support.
Found by Fengguang Wu's test system.
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Link: http://lkml.kernel.org/r/20140213124550.GA30497@localhost
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: <stable@vger.kernel.org> # v3.7+
This is a workaround for HT-enabled STAs which break the spec
and have no HT capabilities RX mask (no HT RX MCS map).
As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
Firmware asserts if such situation occurs.
Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Sometimes, there might be bugs caused by unexpected AML which is compliant
to the Windows but not compliant to the Linux implementation.
There is a predefined validation mechanism implemented in ACPICA to repair
the unexpected AML evaluation results that are caused by the unexpected
AMLs. For example, BIOS may return misorder _CST result and the repair
mechanism can make an ascending order on the returned _CST package object
based on the C-state type.
This mechanism is quite useful to implement an AML interpreter with better
compliance with the real world where Windows is the de-facto standard and
BIOS codes are only tested on one platform thus not compliant to the
ACPI specification.
But if a compliance issue hasn't been figured out yet, it will be
difficult for developers to identify if the unexpected evaluation result
is caused by this mechanism or by the AML interpreter.
For example, _PR0 is expected to be a control method, but BIOS may use
Package: "Name(_PR0, Package(1) {P1PR})".
This boot option can disable the predefined validation mechanism so that
developers can make sure the root cause comes from the parser/executer.
This patch adds a new kernel parameter to disable this feature.
A build test has been made on a Dell Inspiron mini 1100 (i386 z530)
machine when this patch is applied and the corresponding boot test is
performed w/ or w/o the new kernel parameter specified.
References: https://bugzilla.kernel.org/show_bug.cgi?id=67901
Tested-by: Fabian Wehning <fabian.wehning@googlemail.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
In case of warm reset target need to be suspended.
Suspend function is extented to handle both cases
with disabling interrupts and without disabling interrupts.
Warm target reset requires suspend with all interrupts
disabled.
This patch depends on
ath10k: fix device initialization routine
Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Suspend/resume callbacks are not protected by configuration mutex
so adding such protection. Also in order to simplify implemetation
of suspend function wait queue is replaced by completion.
Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Remove translation protection for applications as Linux tools folder will
start to use such types.
In Linux kernel source tree, after removing this translation protection,
the u8/u16/u32/u64/s32/s64 typedefs are exposed for both __KERNEL__ builds
and !__KERNEL__ builds (tools/power/acpi) and the original definitions of
ACPI_UINT8/16/32/64_MAX are changed.
For !__KERNEL__ builds, this kind of defintions should already been tested
by the distribution vendors that are distributing binary ACPICA package and
we've achieved the successful built/run test result in the kernel source
tree.
For __KERNEL__ builds, there are 2 things affected:
1. u8/u16/u32/u64/s32/s64 type definitions:
Since Linux has already type defined u8/u16/u32/u64/s32/s64 in
include/uapi/asm-generic/int-ll64.h for __KERNEL__. In order not to
introduce build regressions where the 2 typedefs are differed,
ACPI_USE_SYSTEM_INTTYPES is introduced to mask out ACPICA's typedefs.
It must be defined for Linux __KERNEL__ builds.
2. ACPI_UINT8/16/32/64_MAX definitions:
Before applying this change:
ACPI_UINT8_MAX: sizeof (UINT8)
UINT8: unsigned char
ACPI_UINT16_MAX: sizeof (UINT16)
UINT16: unsigned short
ACPI_UINT32_MAX: sizeof (UINT32)
INT32: int
UINT32: unsigned int
ACPI_UINT64_MAX: sizeof (UINT64)
INT64: COMPILER_DEPENDENT_INT64
COMPILER_DEPENDENT_INT64: signed long (IA64) or
signed long long (IA32)
UINT64: COMPILER_DEPENDENT_UINT64
COMPILER_DEPENDENT_UINT64: unsigned long (IA64) or
unsigned long long (IA32)
After applying this change:
ACPI_UINT8_MAX: sizeof (u8)
u8: unsigned char
UINT8: (removed from actypes.h)
ACPI_UINT16_MAX: sizeof (u16)
u16: unsigned short
UINT16: (removed from actypes.h)
ACPI_UINT32_MAX: sizeof (u32)
INT32/UINT32: (removed from actypes.h)
s32: signed int
u32: unsigned int
ACPI_UINT64_MAX: sizeof (u64)
INT64/UINT64: (removed from actypes.h)
u64: unsigned long long
s64: signed long long
COMPILER_DEPENDENT_INT64: signed long (IA64) (not used any more)
signed long long (IA32) (not used any more)
COMPILER_DEPENDENT_UINT64: unsigned long (IA64) (not used any more)
unsigned long long (IA32) (not used any more)
All definitions are equal except ACPI_UINT64_MAX for CONFIG_IA64. It
is changed from sizeof(unsigned long) to sizeof(unsigned long long).
By investigation, 64bit Linux kernel build is LP64 compliant, i.e.,
sizeof(long) and (pointer) are 64. As sizeof(unsigned long) equals to
sizeof(unsigned long long) on IA64 platform where CONFIG_64BIT cannot be
disabled, this change actually will not affect the value of
ACPI_UINT64_MAX on IA64 platforms.
This patch is necessary for the ACPICA's acpidump tool to build
correctly. Lv Zheng.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Retrying indefinitely places too much trust on the aux implementation of
the sink devices.
Reported-by: Daniel Martin <consume.noise@gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71267
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Cc: stable@vger.kernel.org
Tested-by: Theodore Ts'o <tytso@mit.edu>
Tested-by: Sree Harsha Totakura <freedesktop@h.totakura.in>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Give more slack to sink devices before retrying on native aux
defer. AFAICT the 100 us timeout was not based on the DP spec.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Cc: stable@vger.kernel.org (on Jani's request)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Hardware CUS232 version 2 has some issues with cold
reset that lead to Data Bus Errors or system hangs
in some cases. It's safer to use warm reset when
possible as it shouldn't trigger the
aforementioned issues.
Prefer warm reset over cold reset. However since
warm reset doesn't work after FW crash make sure to
fallback to cold reset when booting up the HW.
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
It was found during testing the nss calculation does not
cover all corner cases. Station could request eq. only MCS8
and MCS9 (nss=2 specific). Next num_rates=2 so the driver
sets nss=(max((2+7)/8, 1))=1. Which is wrong. The in-driver
calculation was introduced prior (commit ddcc347b70
mac80211: fix rx_nss calculation for drivers with hw rc).
Since it's fixed, use mac80211 provided value from now.
End user will experience lower throuhputs than expected
if the nss is wrongly calculated.
Signed-off-by: Marek Kwaczynski <marek.kwaczynski@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This throw a lot of pointless warnings in case of DFS (radar
detection) and PHYERR events from firmware, when firmware may
actually insert more data, than we assume.
Besides of being noisy this debug does not protect or check
anything usefull currently. It was introduced long time ago
while debugging aggregations. So just removing it.
Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Show message length and expected length. Helps debug
firmware mismatch issues.
Signed-off-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Linux kernel resident ACPICA headers include some sparse declarators for
kernel static checkers. This patch adds code to disable them for non
__KERNEL__ defined code so that it is possible for the ACPICA user space
tool's source files to be built with Linux kernel ACPICA header files
included. Lv Zheng.
Linux kernel build is not affected by this commit.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This urgent patch is cherry picked from ACPICA upstream.
It is reported that some platforms fail to boot without this new _OSI
string.
This change adds this string for Windows 8.1 and Server 2012 R2.
Reported-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Bob Moore <Robert.Moore@intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Fix incorrect sscanf() string in function acpi_battery_alarm_store().
Signed-off-by: Luis G.F <luisgf@luisgf.es>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The ACPI thermal driver defines acpi_thermal_resume() when
CONFIG_PM_SLEEP is defined. This results in the following compile
error when CONFIG_PM_SLEEP is undefined.
CC drivers/acpi/thermal.o
drivers/acpi/thermal.c:107:8: error: ‘acpi_thermal_resume’ undeclared here (not in a function)
make[2]: *** [drivers/acpi/thermal.o] Error 1
Signed-off-by: Shuah Khan <shuah.kh@samsung.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The ACPI SBS driver defines acpi_sbs_resume() when CONFIG_PM_SLEEP is
defined. This results in the following compile error when CONFIG_PM_SLEEP
is undefined:
CC [M] drivers/acpi/sbs.o
drivers/acpi/sbs.c:674:8: error: ‘acpi_sbs_resume’ undeclared here (not in a function)
Signed-off-by: Shuah Khan <shuah.kh@samsung.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The ACPI fan driver defines acpi_fan_suspend() and acpi_fan_resume()
when CONFIG_PM_SLEEP is defined. This results in the following compile
errors when CONFIG_PM_SLEEP is undefined:
drivers/acpi/fan.c:60:8: error: ‘acpi_fan_suspend’ undeclared here (not in a function)
drivers/acpi/fan.c:60:8: error: ‘acpi_fan_resume’ undeclared here (not in a function)
Signed-off-by: Shuah Khan <shuah.kh@samsung.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The ACPI button driver defines acpi_button_resume() when
CONFIG_PM_SLEEP is defined. This results in the following
compile error when CONFIG_PM_SLEEP is undefined:
drivers/acpi/button.c:85:8: error: ‘acpi_button_resume’ undeclared here (not in a function)
Signed-off-by: Shuah Khan <shuah.kh@samsung.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The ACPI battery driver defines acpi_battery_resume() when
CONFIG_PM_SLEEP is defined. This results in the following compile
error when CONFIG_PM_SLEEP is undefined:
drivers/acpi/battery.c:847:8: error: ‘acpi_battery_resume’ undeclared here (not in a function)
Signed-off-by: Shuah Khan <shuah.kh@samsung.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The ACPI AC driver defines acpi_ac_resume() when CONFIG_PM_SLEEP is
defined. This results in the following compile error when
CONFIG_PM_SLEEP is undefined:
drivers/acpi/ac.c:248:8: error: ‘acpi_ac_resume’ undeclared here (not in a function)
Signed-off-by: Shuah Khan <shuah.kh@samsung.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
NICs supported by iwldvm don't handle well TX AMPDU.
Disable it by default, still leave the possibility to
the user to force enable it with a debug parameter.
NICs supported by iwlmvm don't suffer from the same issue,
leave TX AMPDU enabled by default for these.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
If no device tree node existed for a device when CONFIG_OF_GPIO was
defined, then gpio_base would not default to -1.
Signed-off-by: Aaron Sierra <asierra@xes-inc.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Add the NXP PCA9698 40-bit GPIO expander to the supported list.
Note: This only enables GPIO functionality.
Tested-by: Bob Schmitz <bschmitz@xes-inc.com>
Signed-off-by: Aaron Sierra <asierra@xes-inc.com>
Acked-by: Graeme Smecher <gsmecher@threespeedlogic.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
The pca953x driver supports tca6424 (24-bit) and pca9505 (40-bit)
devices. They were the only supported devices not mentioned in the
Kconfig help.
Signed-off-by: Aaron Sierra <asierra@xes-inc.com>
Acked-by: Graeme Smecher <gsmecher@threespeedlogic.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
which is already found in the common header for adp5588
Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
Acked-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
to comply with the rest of the GPIO drivers.
Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
Acked-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
As discussed here: http://ez.analog.com/message/35852,
the 5587 revC and 5588 revB spec sheets contain a mistake
in the GPIO_DAT_STATx register description.
According to R.Shnell at ADI, as well as my own
observations, it should read:
"GPIO data status (shows GPIO state when read for inputs)".
This commit changes the get value function accordingly.
Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
Acked-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
There's no way the driver can pre-build the radiotap header,
so remove the comment stating that it can.
Reported-by: Jouni Malinen <j@w1.fi>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
With module support gone, a lot of functions no longer need to be
exported. Unexport them.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
cgroup_attach_task() is planned to go through restructuring. Let's
tidy it up a bit in preparation.
* Update cgroup_attach_task() to receive the target task argument in
@leader instead of @tsk.
* Rename @tsk to @task.
* Rename @retval to @ret.
This is purely cosmetic.
v2: get_nr_threads() was using uninitialized @task instead of @leader.
Fixed. Reported by Dan Carpenter.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
The two functions don't have any users left. Remove them along with
cgroup_taskset->cur_cgrp.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
cgroup_taskset_cur_css() will be removed during the planned
resturcturing of migration path. The only use of
cgroup_taskset_cur_css() is finding out the old cgroup_subsys_state of
the leader in cpuset_attach(). This usage can easily be removed by
remembering the old value from cpuset_can_attach().
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
If !NULL, @skip_css makes cgroup_taskset_for_each() skip the matching
css. The intention of the interface is to make it easy to skip css's
(cgroup_subsys_states) which already match the migration target;
however, this is entirely unnecessary as migration taskset doesn't
include tasks which are already in the target cgroup. Drop @skip_css
from cgroup_taskset_for_each().
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Daniel Borkmann <dborkman@redhat.com>
Instead of repeatedly locking and unlocking css_set_rwsem inside
cgroup_task_migrate(), update cgroup_attach_task() to grab it outside
of the loop and update cgroup_task_migrate() to use
put_css_set_locked().
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
put_css_set() is performed in two steps - it first tries to put
without grabbing css_set_rwsem if such put wouldn't make the count
zero. If that fails, it puts after write-locking css_set_rwsem. This
patch separates out the second phase into put_css_set_locked() which
should be called with css_set_rwsem locked.
Also, put_css_set_taskexit() is droped and put_css_set() is made to
take @taskexit. There are only a handful users of these functions.
No point in providing different variants.
put_css_locked() will be used by later changes. This patch doesn't
introduce any functional changes.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Now that css_task_iter_start/next_end() supports blocking while
iterating, there's no reason to use css_scan_tasks() which is more
cumbersome to use and scheduled to be removed.
Convert all css_scan_tasks() usages in cpuset to
css_task_iter_start/next/end(). This simplifies the code by removing
heap allocation and callbacks.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Currently there are two ways to walk tasks of a cgroup -
css_task_iter_start/next/end() and css_scan_tasks(). The latter
builds on the former but allows blocking while iterating.
Unfortunately, the way css_scan_tasks() is implemented is rather
nasty, it uses a priority heap of pointers to extract some number of
tasks in task creation order and loops over them invoking the callback
and repeats that until it reaches the end. It requires either
preallocated heap or may fail under memory pressure, while unlikely to
be problematic, the complexity is O(N^2), and in general just nasty.
We're gonna convert all css_scan_users() to
css_task_iter_start/next/end() and remove css_scan_users(). As
css_scan_tasks() users may block, let's convert css_set_lock to a
rwsem so that tasks can block during css_task_iter_*() is in progress.
While this does increase the chance of possible deadlock scenarios,
given the current usage, the probability is relatively low, and even
if that happens, the right thing to do is updating the iteration in
the similar way to css iterators so that it can handle blocking.
Most conversions are trivial; however, task_cgroup_path() now expects
to be called with css_set_rwsem locked instead of locking itself.
This is because the function is called with RCU read lock held and
rwsem locking should nest outside RCU read lock.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Reimplement cgroup_transfer_tasks() so that it repeatedly fetches the
first task in the cgroup and then tranfers it. This achieves the same
result without using css_scan_tasks() which is scheduled to be
removed.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
cgroup_task_count() read-locks css_set_lock and walks all tasks to
count them and then returns the result. The only thing all the users
want is determining whether the cgroup is empty or not. This patch
implements cgroup_has_tasks() which tests whether cgroup->cset_links
is empty, replaces all cgroup_task_count() usages and unexports it.
Note that the test isn't synchronized. This is the same as before.
The test has always been racy.
This will help planned css_set locking update.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Acked-by: Michal Hocko <mhocko@suse.cz>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Balbir Singh <bsingharora@gmail.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Move it above so that prototype isn't necessary. Let's also move the
definition of use_task_css_set_links next to it.
This is purely cosmetic.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Tasks are not linked on their css_sets until cgroup task iteration is
actually used. This is to avoid incurring overhead on the fork and
exit paths for systems which have cgroup compiled in but don't use it.
This lazy binding also affects the task migration path. It has to be
careful so that it doesn't link tasks to css_sets when task_cg_lists
linking is not enabled yet. Unfortunately, this conditional linking
in the migration path interferes with planned migration updates.
This patch moves the lazy binding a bit earlier, to the first cgroup
mount. It's a clear indication that cgroup is being used on the
system and task_cg_lists linking is highly likely to be enabled soon
anyway through "tasks" and "cgroup.procs" files.
This allows cgroup_task_migrate() to always link @tsk->cg_list. Note
that it may still race with cgroup_post_fork() but who wins that race
is inconsequential.
While at it, make use_task_css_set_links a bool, add sanity checks in
cgroup_enable_task_cg_lists() and css_task_iter_start(), and update
the former so that it's guaranteed and assumes to run only once.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Before kernfs conversion, due to the way super_block lookup works,
cgroup roots were created and made visible before being fully
initialized. This in turn required a special flag to mark that the
root hasn't been fully initialized so that the destruction path can
tell fully bound ones from half initialized.
That flag is CGRP_ROOT_SUBSYS_BOUND and no longer necessary after the
kernfs conversion as the lookup and creation of new root are atomic
w.r.t. cgroup_mutex. This patch removes the flag and passes the
requests subsystem mask to cgroup_setup_root() so that it can set the
respective mask bits as subsystems are bound.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>