On resume, before starting the PAL state machine, check if the
adjust_link() method is well supplied. If not, this would lead to a
NULL pointer dereference in the phy_state_machine() function.
This scenario can happen if the Ethernet driver call manually the PHY
functions instead of using the PAL state machine. The mv643xx_eth driver
is a such example.
Signed-off-by: Simon Guinot <sguinot@lacie.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
IEEE 802.3ae clause 45 specifies a somewhat modified MDIO protocol
for use by 10GIGE phys. The main change is a 21 bit address split into
a 5 bit device ID and a 16 bit register offset. The definition is designed
so that normal and extended devices can run on the same MDIO bus.
Extend mdio-bitbang to do the new protocol. At the MDIO bus level the
protocol is requested by or'ing MII_ADDR_C45 into the register offset.
Make phy_read/phy_write/etc pass a full 32 bit register offset.
This does not attempt to make the phy layer support C45 style PHYs, just
to provide the MDIO bus support.
Tested against a Broadcom 10GE phy with ID 0x206034, and several
Broadcom 10/100/1000 Phys in normal mode.
Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Since hibernation assumes power loss, we should fully reinitialize
PHYs (including platform fixups), as if PHYs were just attached.
This patch factors phy_init_hw() out of phy_attach_direct(), then
converts mdio_bus to dev_pm_ops and adds an appropriate restore()
callback.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Sometimes kernel hangs on resume with the following trace:
ucc_geth e0102000.ucc: resume
INFO: task bash:1764 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
bash D 0fecf43c 0 1764 1763 0x00000000
Call Trace:
[cf9a7c10] [c0012868] ret_from_except+0x0/0x14 (unreliable)
--- Exception: cf9a7ce0 at __switch_to+0x4c/0x6c
LR = 0xcf9a7cc0
[cf9a7cd0] [c0008c14] __switch_to+0x4c/0x6c (unreliable)
[cf9a7ce0] [c028bcfc] schedule+0x158/0x260
[cf9a7d10] [c028c720] __mutex_lock_slowpath+0x80/0xd8
[cf9a7d40] [c01cf388] phy_stop+0x20/0x70
[cf9a7d50] [c01d514c] ugeth_resume+0x6c/0x13c
[...]
Here is why.
On suspend:
- PM core starts suspending devices, ucc_geth_suspend gets called;
- ucc_geth calls phy_stop() on suspend. Note that phy_stop() is
mostly asynchronous so it doesn't block ucc_geth's suspend routine,
it just sets PHY_HALTED state and disables PHY's interrupts;
- Suddenly the state machine gets scheduled, it grabs the phydev->lock
mutex and tries to process the PHY_HALTED state, so it calls
phydev->adjust_link(phydev->attached_dev). In ucc_geth case
adjust_link() calls msleep(), which reschedules the code flow back to
PM core, which now finishes suspend and so we end up sleeping with
phydev->lock mutex held.
On resume:
- PM core starts resuming devices (notice that nobody rescheduled
the state machine yet, so the mutex is still held), the core calls
ucc_geth's resume routine;
- ucc_geth_resume restarts the PHY with phy_stop()/phy_start()
sequence, and the phy_*() calls are trying to grab the phydev->lock
mutex. Here comes the deadlock.
This patch fixes the issue by stopping the state machine on suspend
and starting it again on resume.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This patch makes changes in preparation for supporting open firmware
device tree descriptions of MDIO busses. Changes include:
- Cleanup handling of phy_map[] entries; they are already NULLed when
registering and so don't need to be re-cleared, and it is good practice
to clear them out when unregistering.
- Split phy_device registration out into a new function so that the
OF helpers can do two stage registration (separate allocation and
registration steps).
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
In most cases (e.g. PCI drivers) MDIO and MAC controllers are
represented by the same device. But for SOC ethernets we have
separate devices. So, in SOC case, checking whether MDIO
controller may wakeup is not only makes little sense, but also
prevents us from doing per-netdevice wakeup management.
This patch reworks suspend/resume code so that now it checks
for net device's wakeup flags, not MDIO controller's ones.
Each netdevice should manage its wakeup flags, and phylib will
decide whether suspend an attached PHY or not.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Suspend/resume routines check for phydrv != NULL, but that is
wrong because "phydrv" comes from container_of(drv). If drv is NULL,
then container_of(drv) will return non-NULL result, and the checks
won't work.
The Freescale TBI PHYs are driver-less, so "drv" is NULL, and that
leads to the following oops:
Unable to handle kernel paging request for data at address 0xffffffe4
Faulting instruction address: 0xc0215554
Oops: Kernel access of bad area, sig: 11 [#1]
[...]
NIP [c0215554] mdio_bus_suspend+0x34/0x70
LR [c01cc508] suspend_device+0x258/0x2bc
Call Trace:
[cfad3da0] [cfad3db8] 0xcfad3db8 (unreliable)
[cfad3db0] [c01cc508] suspend_device+0x258/0x2bc
[cfad3dd0] [c01cc62c] dpm_suspend+0xc0/0x140
[cfad3e20] [c01cc6f4] device_suspend+0x48/0x5c
[cfad3e40] [c0068dd8] suspend_devices_and_enter+0x8c/0x148
[cfad3e60] [c00690f8] enter_state+0x100/0x118
[cfad3e80] [c00691c0] state_store+0xb0/0xe4
[cfad3ea0] [c018c938] kobj_attr_store+0x24/0x3c
[cfad3eb0] [c00ea9a8] flush_write_buffer+0x58/0x7c
[cfad3ed0] [c00eadf0] sysfs_write_file+0x58/0xa0
[cfad3ef0] [c009e810] vfs_write+0xb4/0x16c
[cfad3f10] [c009ed40] sys_write+0x4c/0x90
[cfad3f40] [c0014954] ret_from_syscall+0x0/0x38
[...]
This patch fixes the issue, plus removes unneeded parentheses
and fixes indentation level in mdio_bus_suspend().
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
The PHYLIB mdio code has more problems in error paths:
- mdiobus_release can be called before bus->state is set to
MDIOBUS_REGISTERED
- mdiobus_scan allocates resources which need to be freed
- the comment is wrong, the resistors used are actually pull-ups.
Signed-off-by: Krzysztof Halasa <khc@pm.waw.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
kernel BUG at drivers/net/phy/mdio_bus.c:165!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
How?
mdiobus_alloc() sets bus->state = MDIOBUS_ALLOCATED.
mdiobus_register() sets bus->state = MDIOBUS_REGISTERED but then can
fail (mdiobus_scan()) returning an error to the caller.
The caller aborts correctly with mdiobus_free() which does:
if (bus->state == MDIOBUS_ALLOCATED) {
kfree(bus);
return;
}
BUG_ON(bus->state != MDIOBUS_UNREGISTERED);
Signed-off-by: Krzysztof Halasa <khc@pm.waw.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
This patch adds the power management support into the physical
abstraction layer.
Suspend and resume functions respectively turns on/off the bit 11
into the PHY Basic mode control register.
Generic PHY device starts supporting PM.
In order to support the wake-on LAN and avoid to put in power down
the PHY device, the MDIO is aware of what the Ethernet device wants to do.
Voluntary, no CONFIG_PM defines were added into the sources.
Also generic suspend/resume functions are exported to allow
other drivers use them (such as genphy_config_aneg etc.).
Within the phy_driver_register function, we need to remove the
memset. It overrides the device driver owner and it is not good.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Commit 46abc02175 ("phylib: give mdio
buses a device tree presence") added a call to device_unregister() in
a situation where the caller did not intend for the device to be
freed yet, but apart from just unregistering the device from the
system, device_unregister() does an additional put_device() that is
intended to free it.
The right function to use in this situation is device_del(), which
unregisters the device from the system like device_unregister() does,
but without dropping the reference count an additional time.
Bug report from Bryan Wu <cooloney@kernel.org>.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Tested-by: Bryan Wu <cooloney@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Fix kernel-doc warning, missing description:
Warning(lin2627-g3-kdocfixes//drivers/net/phy/mdio_bus.c:63): No description found for parameter 'd'
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Add mdiobus_{read,write} routines to allow direct reading/writing
of registers on an mii bus without having to go through the PHY
abstraction, and make phy_{read,write} use these primitives.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Introduce the mdio_bus class, and give each 'struct mii_bus' its own
'struct device', so that mii_bus objects are represented in the device
tree and can be found by querying the device tree.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Acked-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This patch introduces mdiobus_alloc() and mdiobus_free(), and
makes all mdio bus drivers use these functions to allocate their
struct mii_bus'es dynamically.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Andy Fleming <afleming@freescale.com>
In preparation of giving mii_bus objects a device tree presence of
their own, rename struct mii_bus's ->dev argument to ->parent, since
having a 'struct device *dev' that points to our parent device
conflicts with introducing a 'struct device dev' representing our own
device.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Andy Fleming <afleming@freescale.com>
This patch splits the bus scanning code in mdiobus_register() off
into a separate function, and makes this function available for
calling from external code. This allows incrementally scanning an
mii bus, e.g. as information about which addresses are 'safe' to
scan becomes available.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Acked-by: Andy Fleming <afleming@freescale.com>
Sometimes the specific interaction between the platform and the PHY
requires special handling. For instance, to change where the PHY's
clock input is, or to add a delay to account for latency issues in the
data path. We add a mechanism for registering a callback with the PHY
Lib to be called on matching PHYs when they are brought up, or reset.
Signed-off-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This patch fixes a check-after-use spotted by the Coverity checker.
Signed-off-by: Adrian Bunk <bunk@kernel.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
PHY read/write functions can potentially sleep (e.g., a PHY accessed
via I2C). The following changes were made to account for this:
* Change spin locks to mutex locks
* Add a BUG_ON() to phy_read() phy_write() to warn against
calling them from an interrupt context.
* Use work queue for PHY state machine handling since
it can potentially sleep
* Change phydev lock from spinlock to mutex
Signed-off-by: Nate Case <ncase@xes-inc.com>
Acked-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Lately I've got this nice badness on mdio bus removal:
Device 'e0103120:06' does not have a release() function, it is broken and must be fixed.
------------[ cut here ]------------
Badness at drivers/base/core.c:107
NIP: c015c1a8 LR: c015c1a8 CTR: c0157488
REGS: c34bdcf0 TRAP: 0700 Not tainted (2.6.23-rc5-g9ebadfbb-dirty)
MSR: 00029032 <EE,ME,IR,DR> CR: 24088422 XER: 00000000
...
[c34bdda0] [c015c1a8] device_release+0x78/0x80 (unreliable)
[c34bddb0] [c01354cc] kobject_cleanup+0x80/0xbc
[c34bddd0] [c01365f0] kref_put+0x54/0x6c
[c34bdde0] [c013543c] kobject_put+0x24/0x34
[c34bddf0] [c015c384] put_device+0x1c/0x2c
[c34bde00] [c0180e84] mdiobus_unregister+0x2c/0x58
...
Though actually there is nothing broken, it just device
subsystem core expects another "pattern" of resource managment.
This patch implement phy device's release function, thus
we're getting rid of this badness.
Also small hidden bug fixed, hope none other introduced. ;-)
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Acked-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
The phy_id specified for the Vitesse 824x PHY would never match because
it was expecting bits to be set that would be masked by the phy_id_mask.
Fix the phy_id so it will match properly, and changed the mdio_bus_match
to mask both the driver and devices phy_id with the mask so we dont have
this issue in the future.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Convert function documentation in drivers/net/phy/ to kernel-doc
and add it to DocBook.
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
After Al Viro (finally) succeeded in removing the sched.h #include in module.h
recently, it makes sense again to remove other superfluous sched.h includes.
There are quite a lot of files which include it but don't actually need
anything defined in there. Presumably these includes were once needed for
macros that used to live in sched.h, but moved to other header files in the
course of cleaning it up.
To ease the pain, this time I did not fiddle with any header files and only
removed #includes from .c-files, which tend to cause less trouble.
Compile tested against 2.6.20-rc2 and 2.6.20-rc2-mm2 (with offsets) on alpha,
arm, i386, ia64, mips, powerpc, and x86_64 with allnoconfig, defconfig,
allmodconfig, and allyesconfig as well as a few randconfigs on x86_64 and all
configs in arch/arm/configs on arm. I also checked that no new warnings were
introduced by the patch (actually, some warnings are removed that were emitted
by unnecessarily included header files).
Signed-off-by: Tim Schmielau <tim@physik3.uni-rostock.de>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This makes it possible for HW PHY-less boards to utilize PAL goodies. Generic
routines to connect to fixed PHY are provided, as well as ability to specify
software callback that fills up link, speed, etc. information into PHY
descriptor (the latter feature not tested so far).
Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
make sure phy_map entries whose PHY address is masked are initialized
to NULL, given that other code (such as mdiobus_unregister for
instance) assumes that non-NULL phy_map entries are allocated
phy_devices
Signed-off-by: Herbert Valerio Riedel <hvr@gnu.org>
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Add the PHY_ID_FMT macro to ensure that the format of the id string used by a
driver to match to its specific phy is consistent between the mdio_bus and the
driver.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Adds a phy_mask field to struct mii_bus and uses it. This field
indicates each phy address to be ignored when probing the mdio bus.
This support is needed for the fs_enet and ibm_emac drivers to be
converted to the generic phy layer among other drivers. Many systems
lock up on probing certain phy addresses or probing doesn't return
0xffff when nothing is found at the address. A new driver I'm
working on also makes use of this mask.
Signed-off-by: Matt Porter <mporter@kernel.crashing.org>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
In PM v1, all devices were called at SUSPEND_DISABLE level. Then
all devices were called at SUSPEND_SAVE_STATE level, and finally
SUSPEND_POWER_DOWN level. However, with PM v2, to maintain
compatibility for platform devices, I arranged for the PM v2
suspend/resume callbacks to call the old PM v1 suspend/resume
callbacks three times with each level in order so that existing
drivers continued to work.
Since this is obsolete infrastructure which is no longer necessary,
we can remove it. Here's an (untested) patch to do exactly that.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
When building with CONFIG_PHYLIB=y on Itanium, I see:
`mdio_bus_exit' referenced in section `.init.text' of
drivers/built-in.o: defined in discarded section `.exit.text' of
drivers/built-in.o
I believe that mdio_bus_exit should not be declared __exit, because it is
referencesd from __init sections in, say, phy_init().
Signed-off-by: Peter Chubb <peterc@gelato.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Fix remaining bits of u32 vs. pm_message confusion. Should not break
anything.
Signed-off-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This patch adds back the code that was taken out, thus re-enabling:
* The PHY Layer to initialize without crashing
* Drivers to actually connect to PHYs
* The entire PHY Control Layer
This patch is used by the gianfar driver, and other drivers which are in
development.
Signed-off-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
ethernet drivers to remain as ignorant as is reasonable of the connected
PHY's design and operation details.
Signed-off-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>