* [PATCH 3/4] of/mdio: add context argument to adjust link callback
From: s-paulraj @ 2012-07-06 20:09 UTC (permalink / raw)
To: netdev, davem, cyril, grant.likely, linux-keystone; +Cc: Sandeep Paulraj
From: Sandeep Paulraj <s-paulraj@ti.com>
This patch implements extensions to device-tree phy interfaces in order to
have context information passed back into the adjust link callbacks.
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
---
drivers/of/of_mdio.c | 24 +++++++++++++++---------
include/linux/of_mdio.h | 15 ++++++++-------
2 files changed, 23 insertions(+), 16 deletions(-)
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 2574abd..a0a09db 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -136,20 +136,24 @@ EXPORT_SYMBOL(of_phy_find_device);
* @phy_np: Pointer to device tree node for the PHY
* @hndlr: Link state callback for the network device
* @iface: PHY data interface type
+ * @context: Context for callback handler
*
* Returns a pointer to the phy_device if successful. NULL otherwise
*/
-struct phy_device *of_phy_connect(struct net_device *dev,
- struct device_node *phy_np,
- void (*hndlr)(struct net_device *), u32 flags,
- phy_interface_t iface)
+struct phy_device *
+of_phy_connect(struct net_device *dev,
+ struct device_node *phy_np,
+ void (*hndlr)(struct net_device *, void *context),
+ u32 flags, phy_interface_t iface, void *context)
{
struct phy_device *phy = of_phy_find_device(phy_np);
+ int error;
if (!phy)
return NULL;
- return phy_connect_direct(dev, phy, hndlr, flags, iface) ? NULL : phy;
+ error = phy_connect_direct(dev, phy, hndlr, flags, iface, context);
+ return error ? NULL : phy;
}
EXPORT_SYMBOL(of_phy_connect);
@@ -158,14 +162,16 @@ EXPORT_SYMBOL(of_phy_connect);
* @dev: pointer to net_device claiming the phy
* @hndlr: Link state callback for the network device
* @iface: PHY data interface type
+ * @context: Context for callback handler
*
* This function is a temporary stop-gap and will be removed soon. It is
* only to support the fs_enet, ucc_geth and gianfar Ethernet drivers. Do
* not call this function from new drivers.
*/
-struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
- void (*hndlr)(struct net_device *),
- phy_interface_t iface)
+struct phy_device *
+of_phy_connect_fixed_link(struct net_device *dev,
+ void (*hndlr)(struct net_device *, void *context),
+ phy_interface_t iface, void *context)
{
struct device_node *net_np;
char bus_id[MII_BUS_ID_SIZE + 3];
@@ -186,7 +192,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
sprintf(bus_id, PHY_ID_FMT, "fixed-0", be32_to_cpu(phy_id[0]));
- phy = phy_connect(dev, bus_id, hndlr, 0, iface);
+ phy = phy_connect(dev, bus_id, hndlr, 0, iface, context);
return IS_ERR(phy) ? NULL : phy;
}
EXPORT_SYMBOL(of_phy_connect_fixed_link);
diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
index 912c27a..d72d0c6 100644
--- a/include/linux/of_mdio.h
+++ b/include/linux/of_mdio.h
@@ -14,13 +14,14 @@
extern int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np);
extern struct phy_device *of_phy_find_device(struct device_node *phy_np);
-extern struct phy_device *of_phy_connect(struct net_device *dev,
- struct device_node *phy_np,
- void (*hndlr)(struct net_device *),
- u32 flags, phy_interface_t iface);
-extern struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
- void (*hndlr)(struct net_device *),
- phy_interface_t iface);
+extern struct phy_device *
+of_phy_connect(struct net_device *dev, struct device_node *phy_np,
+ void (*hndlr)(struct net_device *, void *context),
+ u32 flags, phy_interface_t iface, void *context);
+extern struct phy_device *
+of_phy_connect_fixed_link(struct net_device *dev,
+ void (*hndlr)(struct net_device *, void *context),
+ phy_interface_t iface, void *context);
extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/4] phylib: add context argument to adjust link callback
From: s-paulraj @ 2012-07-06 20:09 UTC (permalink / raw)
To: netdev, davem, cyril, grant.likely, linux-keystone; +Cc: Sandeep Paulraj
From: Sandeep Paulraj <s-paulraj@ti.com>
This patch introduces a context argument for the adjust link callback. This
context information is set at phy_connect() (and its variants), and is passed
back into the adjust_link callbacks on link state change events.
Such context information is necessary when a network device has multiple
underlying ports. Specifically, this comes into play when the netdev is
really one of the ports going into an on-chip switch of some sort.
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
---
drivers/net/phy/phy.c | 6 +++---
drivers/net/phy/phy_device.c | 23 +++++++++++++++--------
include/linux/phy.h | 20 ++++++++++++--------
3 files changed, 30 insertions(+), 19 deletions(-)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 36ca912..491a608 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -433,7 +433,7 @@ static void phy_change(struct work_struct *work);
* function.
*/
void phy_start_machine(struct phy_device *phydev,
- void (*handler)(struct net_device *))
+ void (*handler)(struct net_device *, void *context))
{
phydev->adjust_state = handler;
@@ -763,7 +763,7 @@ EXPORT_SYMBOL(phy_start);
static inline void phy_adjust_link(struct phy_device *phydev)
{
- phydev->adjust_link(phydev->attached_dev);
+ phydev->adjust_link(phydev->attached_dev, phydev->context);
}
/**
@@ -781,7 +781,7 @@ void phy_state_machine(struct work_struct *work)
mutex_lock(&phydev->lock);
if (phydev->adjust_state)
- phydev->adjust_state(phydev->attached_dev);
+ phydev->adjust_state(phydev->attached_dev, phydev->context);
switch(phydev->state) {
case PHY_DOWN:
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index de86a55..a4e5313 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -310,6 +310,7 @@ EXPORT_SYMBOL(phy_find_first);
* phy_prepare_link - prepares the PHY layer to monitor link status
* @phydev: target phy_device struct
* @handler: callback function for link status change notifications
+ * @context: context information for callback handler
*
* Description: Tells the PHY infrastructure to handle the
* gory details on monitoring link status (whether through
@@ -319,9 +320,11 @@ EXPORT_SYMBOL(phy_find_first);
* this function.
*/
static void phy_prepare_link(struct phy_device *phydev,
- void (*handler)(struct net_device *))
+ void (*handler)(struct net_device *, void *context),
+ void *context)
{
phydev->adjust_link = handler;
+ phydev->context = context;
}
/**
@@ -331,10 +334,11 @@ static void phy_prepare_link(struct phy_device *phydev,
* @handler: callback function for state change notifications
* @flags: PHY device's dev_flags
* @interface: PHY device's interface
+ * @context: context information for callback handler
*/
int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
- void (*handler)(struct net_device *), u32 flags,
- phy_interface_t interface)
+ void (*handler)(struct net_device *, void *context),
+ u32 flags, phy_interface_t interface, void *context)
{
int rc;
@@ -342,7 +346,7 @@ int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
if (rc)
return rc;
- phy_prepare_link(phydev, handler);
+ phy_prepare_link(phydev, handler, context);
phy_start_machine(phydev, NULL);
if (phydev->irq > 0)
phy_start_interrupts(phydev);
@@ -358,6 +362,7 @@ EXPORT_SYMBOL(phy_connect_direct);
* @handler: callback function for state change notifications
* @flags: PHY device's dev_flags
* @interface: PHY device's interface
+ * @context: context information for callback handler
*
* Description: Convenience function for connecting ethernet
* devices to PHY devices. The default behavior is for
@@ -367,9 +372,10 @@ EXPORT_SYMBOL(phy_connect_direct);
* choose to call only the subset of functions which provide
* the desired functionality.
*/
-struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
- void (*handler)(struct net_device *), u32 flags,
- phy_interface_t interface)
+struct phy_device *
+phy_connect(struct net_device *dev, const char *bus_id,
+ void (*handler)(struct net_device *, void *context),
+ u32 flags, phy_interface_t interface, void *context)
{
struct phy_device *phydev;
struct device *d;
@@ -384,7 +390,8 @@ struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
}
phydev = to_phy_device(d);
- rc = phy_connect_direct(dev, phydev, handler, flags, interface);
+ rc = phy_connect_direct(dev, phydev, handler, flags, interface,
+ context);
if (rc)
return ERR_PTR(rc);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index c291cae..596b8fe 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -263,6 +263,7 @@ enum phy_state {
* changes in the link state.
* adjust_state: Callback for the enet driver to respond to
* changes in the state machine.
+ * context: Context information for adjust_link and adjust_state callbacks
*
* speed, duplex, pause, supported, advertising, and
* autoneg are used like in mii_if_info
@@ -337,9 +338,11 @@ struct phy_device {
struct net_device *attached_dev;
- void (*adjust_link)(struct net_device *dev);
+ void (*adjust_link)(struct net_device *dev, void *context);
- void (*adjust_state)(struct net_device *dev);
+ void (*adjust_state)(struct net_device *dev, void *context);
+
+ void *context;
};
#define to_phy_device(d) container_of(d, struct phy_device, dev)
@@ -487,11 +490,12 @@ struct phy_device * phy_attach(struct net_device *dev,
const char *bus_id, u32 flags, phy_interface_t interface);
struct phy_device *phy_find_first(struct mii_bus *bus);
int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
- void (*handler)(struct net_device *), u32 flags,
- phy_interface_t interface);
-struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
- void (*handler)(struct net_device *), u32 flags,
- phy_interface_t interface);
+ void (*handler)(struct net_device *, void *context),
+ u32 flags, phy_interface_t interface, void *context);
+struct phy_device *
+phy_connect(struct net_device *dev, const char *bus_id,
+ void (*handler)(struct net_device *, void *context),
+ u32 flags, phy_interface_t interface, void *context);
void phy_disconnect(struct phy_device *phydev);
void phy_detach(struct phy_device *phydev);
void phy_start(struct phy_device *phydev);
@@ -514,7 +518,7 @@ void phy_driver_unregister(struct phy_driver *drv);
int phy_driver_register(struct phy_driver *new_driver);
void phy_state_machine(struct work_struct *work);
void phy_start_machine(struct phy_device *phydev,
- void (*handler)(struct net_device *));
+ void (*handler)(struct net_device *, void *context));
void phy_stop_machine(struct phy_device *phydev);
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/4] phylib: factor out handler callouts into helper
From: s-paulraj @ 2012-07-06 20:09 UTC (permalink / raw)
To: netdev, davem, cyril, grant.likely, linux-keystone; +Cc: Sandeep Paulraj
From: Sandeep Paulraj <s-paulraj@ti.com>
This patch pulls out adjust_link handler callbacks into a helper function.
The patch does not modify phylib behavior in any material way.
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
---
drivers/net/phy/phy.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 3cbda08..36ca912 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -761,6 +761,11 @@ void phy_start(struct phy_device *phydev)
EXPORT_SYMBOL(phy_stop);
EXPORT_SYMBOL(phy_start);
+static inline void phy_adjust_link(struct phy_device *phydev)
+{
+ phydev->adjust_link(phydev->attached_dev);
+}
+
/**
* phy_state_machine - Handle the state machine
* @work: work_struct that describes the work to be done
@@ -801,7 +806,7 @@ void phy_state_machine(struct work_struct *work)
if (!phydev->link) {
phydev->state = PHY_NOLINK;
netif_carrier_off(phydev->attached_dev);
- phydev->adjust_link(phydev->attached_dev);
+ phy_adjust_link(phydev);
break;
}
@@ -815,7 +820,7 @@ void phy_state_machine(struct work_struct *work)
if (err > 0) {
phydev->state = PHY_RUNNING;
netif_carrier_on(phydev->attached_dev);
- phydev->adjust_link(phydev->attached_dev);
+ phy_adjust_link(phydev);
} else if (0 == phydev->link_timeout--) {
int idx;
@@ -853,7 +858,7 @@ void phy_state_machine(struct work_struct *work)
if (phydev->link) {
phydev->state = PHY_RUNNING;
netif_carrier_on(phydev->attached_dev);
- phydev->adjust_link(phydev->attached_dev);
+ phy_adjust_link(phydev);
}
break;
case PHY_FORCING:
@@ -872,7 +877,7 @@ void phy_state_machine(struct work_struct *work)
}
}
- phydev->adjust_link(phydev->attached_dev);
+ phy_adjust_link(phydev);
break;
case PHY_RUNNING:
/* Only register a CHANGE if we are
@@ -894,7 +899,7 @@ void phy_state_machine(struct work_struct *work)
netif_carrier_off(phydev->attached_dev);
}
- phydev->adjust_link(phydev->attached_dev);
+ phy_adjust_link(phydev);
if (PHY_POLL != phydev->irq)
err = phy_config_interrupt(phydev,
@@ -904,7 +909,7 @@ void phy_state_machine(struct work_struct *work)
if (phydev->link) {
phydev->link = 0;
netif_carrier_off(phydev->attached_dev);
- phydev->adjust_link(phydev->attached_dev);
+ phy_adjust_link(phydev);
}
break;
case PHY_RESUMING:
@@ -938,7 +943,7 @@ void phy_state_machine(struct work_struct *work)
netif_carrier_on(phydev->attached_dev);
} else
phydev->state = PHY_NOLINK;
- phydev->adjust_link(phydev->attached_dev);
+ phy_adjust_link(phydev);
} else {
phydev->state = PHY_AN;
phydev->link_timeout = PHY_AN_TIMEOUT;
@@ -953,7 +958,7 @@ void phy_state_machine(struct work_struct *work)
netif_carrier_on(phydev->attached_dev);
} else
phydev->state = PHY_NOLINK;
- phydev->adjust_link(phydev->attached_dev);
+ phy_adjust_link(phydev);
}
break;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH 0/4] phylib: add context argument to adjust link callbacks
From: s-paulraj @ 2012-07-06 19:57 UTC (permalink / raw)
To: netdev, davem, cyril, grant.likely, linux-keystone; +Cc: Sandeep Paulraj
From: Sandeep Paulraj <s-paulraj@ti.com>
This series of 4 patches adds a new context argument for the adjust link
callbacks. The existing phy_connect() and its variants don't have a way to
pass any private context information. This becomes necessary when, a SOC
has an on chip switch with multiple ports. We need port specific information
to figure out which port a given callback belongs to.
We can pass this context information in the phy_connect() and its
variants. This in turn gets passed into the adjust link callbacks on link
state change events.
NOTE: At this point of time patch 4 in this series passes a "NULL" to
the phy_connect() and its variants for all drivers that currently use
phy_connect() and its variants. This patch has been tested on a
Texas Instruments SOC, patches for which, as of now have not yet been
upstreamed; as a result of which this patch series does not yet
have an example of how this new feature is being actually used.
Sandeep Paulraj (4):
phylib: factor out handler callouts into helper
phylib: add context argument to adjust link callback
of/mdio: add context argument to adjust link callback
net: add context callback parameter to phy connect
drivers/net/ethernet/8390/ax88796.c | 4 ++--
drivers/net/ethernet/adi/bfin_mac.c | 4 ++--
drivers/net/ethernet/aeroflex/greth.c | 7 +++---
drivers/net/ethernet/amd/au1000_eth.c | 4 ++--
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 4 ++--
drivers/net/ethernet/broadcom/sb1250-mac.c | 6 ++---
drivers/net/ethernet/broadcom/tg3.c | 4 ++--
drivers/net/ethernet/cadence/macb.c | 4 ++--
drivers/net/ethernet/dnet.c | 6 ++---
drivers/net/ethernet/ethoc.c | 4 ++--
drivers/net/ethernet/faraday/ftgmac100.c | 4 ++--
drivers/net/ethernet/freescale/fec.c | 4 ++--
drivers/net/ethernet/freescale/fec_mpc52xx.c | 5 ++--
.../net/ethernet/freescale/fs_enet/fs_enet-main.c | 6 ++---
drivers/net/ethernet/freescale/gianfar.c | 8 +++----
drivers/net/ethernet/freescale/ucc_geth.c | 6 ++---
drivers/net/ethernet/lantiq_etop.c | 4 ++--
drivers/net/ethernet/nxp/lpc_eth.c | 5 ++--
drivers/net/ethernet/octeon/octeon_mgmt.c | 4 ++--
drivers/net/ethernet/pasemi/pasemi_mac.c | 4 ++--
drivers/net/ethernet/rdc/r6040.c | 4 ++--
drivers/net/ethernet/renesas/sh_eth.c | 4 ++--
drivers/net/ethernet/s6gmac.c | 4 ++--
drivers/net/ethernet/smsc/smsc911x.c | 4 ++--
drivers/net/ethernet/smsc/smsc9420.c | 5 ++--
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++--
drivers/net/ethernet/ti/cpmac.c | 4 ++--
drivers/net/ethernet/ti/cpsw.c | 5 ++--
drivers/net/ethernet/ti/davinci_emac.c | 4 ++--
drivers/net/ethernet/toshiba/tc35815.c | 5 ++--
drivers/net/ethernet/xilinx/ll_temac_main.c | 4 ++--
drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 3 ++-
drivers/net/ethernet/xilinx/xilinx_emaclite.c | 5 ++--
drivers/net/ethernet/xscale/ixp4xx_eth.c | 4 ++--
drivers/net/phy/phy.c | 25 ++++++++++++--------
drivers/net/phy/phy_device.c | 23 +++++++++++-------
drivers/of/of_mdio.c | 24 ++++++++++++-------
include/linux/of_mdio.h | 15 ++++++------
include/linux/phy.h | 20 +++++++++-------
39 files changed, 149 insertions(+), 116 deletions(-)
--
1.7.9.5
^ permalink raw reply
* Re: Network namespace and bonding WARNING at fs/proc/generic.c remove_proc_entry
From: Serge E. Hallyn @ 2012-07-06 19:47 UTC (permalink / raw)
To: Eric W. Biederman
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Dilip Daya, linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <87fw94g1kq.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
Quoting Eric W. Biederman (ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org):
> "Serge E. Hallyn" <serge-A9i7LUbDfNHQT0dZR+AlfA@public.gmane.org> writes:
>
> >> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> >> index 2ee8cf9..818ed64 100644
> >> --- a/drivers/net/bonding/bond_main.c
> >> +++ b/drivers/net/bonding/bond_main.c
> >> @@ -4345,6 +4345,9 @@ static void bond_setup(struct net_device *bond_dev)
> >> bond_dev->priv_flags |= IFF_BONDING;
> >> bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
> >>
> >> + /* Don't allow bond devices to change network namespaces. */
> >> + bond_dev->features |= NETIF_F_LOCAL;
> >
> > I believe this needs to be NETIF_F_NETNS_LOCAL. Test build still going with
> > that change.
>
> Yes that is what I mean.
With that change, build is fine, boots fine, I can't pass a bond to another
netns (preventing the problem), and I can create a bond in a child netns
just fine.
Thanks!
Acked-by: Serge Hallyn <serge.hallyn-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
-serge
^ permalink raw reply
* pull request: wireless 2012-07-06
From: John W. Linville @ 2012-07-06 19:20 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 4387 bytes --]
commit 50787c0dfcffe9be908994bdd7bb28b1a49192b5
Dave,
Please accept these fixes for the 3.5 stream...
Eliad Peller provides a mac80211 fix to properly clean-up after an
association failure.
Sasha Levin offers an NFC fix to prevent a NULL pointer derference
in llcp_sock_getname.
Thomas Huehn provides an mwl8k fix for a race that can result in
a use-after-free bug. Also, he provides a mac80211 fix to correct
some kzalloc arguments, and another fix to address an issue found
with that fix after I had already committed the original patch.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit 9e85a6f9dc231f3ed3c1dc1b12217505d970142a:
Merge tag 'clk-fixes-for-linus' of git://git.linaro.org/people/mturquette/linux (2012-07-03 18:06:49 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem
for you to fetch changes up to 50787c0dfcffe9be908994bdd7bb28b1a49192b5:
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem (2012-07-06 14:48:50 -0400)
----------------------------------------------------------------
Eliad Peller (1):
mac80211: destroy assoc_data correctly if assoc fails
John W. Linville (1):
Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem
Sasha Levin (1):
NFC: Prevent NULL deref when getting socket name
Thomas Huehn (3):
mac80211: correct size the argument to kzalloc in minstrel_ht
mwl8k: fix possible race condition in info->control.sta use
mac80211: fix kzalloc memory corruption introduced in minstrel_ht
drivers/net/wireless/mwl8k.c | 3 ++-
net/mac80211/mlme.c | 6 ++----
net/mac80211/rc80211_minstrel_ht.c | 2 +-
net/nfc/llcp/sock.c | 2 +-
4 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index cf7bdc6..1404373 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1665,7 +1665,8 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
info = IEEE80211_SKB_CB(skb);
if (ieee80211_is_data(wh->frame_control)) {
- sta = info->control.sta;
+ sta = ieee80211_find_sta_by_ifaddr(hw, wh->addr1,
+ wh->addr2);
if (sta) {
sta_info = MWL8K_STA(sta);
BUG_ON(sta_info == NULL);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a4bb856..0db5d34 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2174,15 +2174,13 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
sdata->name, mgmt->sa, status_code);
ieee80211_destroy_assoc_data(sdata, false);
} else {
- printk(KERN_DEBUG "%s: associated\n", sdata->name);
-
if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) {
/* oops -- internal error -- send timeout for now */
- ieee80211_destroy_assoc_data(sdata, true);
- sta_info_destroy_addr(sdata, mgmt->bssid);
+ ieee80211_destroy_assoc_data(sdata, false);
cfg80211_put_bss(*bss);
return RX_MGMT_CFG80211_ASSOC_TIMEOUT;
}
+ printk(KERN_DEBUG "%s: associated\n", sdata->name);
/*
* destroy assoc_data afterwards, as otherwise an idle
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 2d1acc6..f9e51ef 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -809,7 +809,7 @@ minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
max_rates = sband->n_bitrates;
}
- msp = kzalloc(sizeof(struct minstrel_ht_sta), gfp);
+ msp = kzalloc(sizeof(*msp), gfp);
if (!msp)
return NULL;
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
index 17a707d..e06d458 100644
--- a/net/nfc/llcp/sock.c
+++ b/net/nfc/llcp/sock.c
@@ -292,7 +292,7 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr,
pr_debug("%p\n", sk);
- if (llcp_sock == NULL)
+ if (llcp_sock == NULL || llcp_sock->dev == NULL)
return -EBADFD;
addr->sa_family = AF_NFC;
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related
* Re: Network namespace and bonding WARNING at fs/proc/generic.c remove_proc_entry
From: Eric W. Biederman @ 2012-07-06 18:57 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Dilip Daya, linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20120706170538.GA31679-7LNsyQBKDXoIagZqoN9o3w@public.gmane.org>
"Serge E. Hallyn" <serge-A9i7LUbDfNHQT0dZR+AlfA@public.gmane.org> writes:
>> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>> index 2ee8cf9..818ed64 100644
>> --- a/drivers/net/bonding/bond_main.c
>> +++ b/drivers/net/bonding/bond_main.c
>> @@ -4345,6 +4345,9 @@ static void bond_setup(struct net_device *bond_dev)
>> bond_dev->priv_flags |= IFF_BONDING;
>> bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
>>
>> + /* Don't allow bond devices to change network namespaces. */
>> + bond_dev->features |= NETIF_F_LOCAL;
>
> I believe this needs to be NETIF_F_NETNS_LOCAL. Test build still going with
> that change.
Yes that is what I mean.
Eric
^ permalink raw reply
* Re: [PATCH] ipv4: Avoid overhead when no custom FIB rules are installed.
From: David Miller @ 2012-07-06 18:53 UTC (permalink / raw)
To: bhutchings; +Cc: netdev
In-Reply-To: <1341595171.2923.2.camel@bwh-desktop.uk.solarflarecom.com>
From: Ben Hutchings <bhutchings@solarflare.com>
Date: Fri, 6 Jul 2012 18:19:31 +0100
> Do you really mean to set fib_has_custom_rules = true on deletion?
Yes, because someone could delete one of the default rules, which
would make our shortcut invalid.
^ permalink raw reply
* Re: Network namespace and bonding WARNING at fs/proc/generic.c remove_proc_entry
From: Eric W. Biederman @ 2012-07-06 18:40 UTC (permalink / raw)
To: dilip.daya; +Cc: Serge E. Hallyn, linux-kernel, containers, netdev
In-Reply-To: <1341597680.2829.22.camel@pro6455b.example.com>
Dilip Daya <dilip.daya@hp.com> writes:
> Hi Eric,
> We do need to move bonds between namespaces - because we require
> physical interfaces in each namespace -- we don't want the overheads of
> virtual interfaces, don't have the management infrastructure, and don't
> want to manufacture fake mac addresses that would be required for
> macvlan interfaces. Since the bonds are implicitly created in the host
> namespace, the only way we know to get bonds directly into the
> namespaces is to move them.
There about 3 ways to create bonding devices. One of those ways
is to create bonding devices when loading the module. Another
way is to create a bond device with "echo '+bond35 > /sys/class/net/bonding_masters".
them when loading the module, and my favorite is the standard way
"ip link add type bond". All but loading the bonding device work in the
network namespace you are in at the type.
> Would "NETDEV_UNREGISTER and NETDEV_REGISTER events to remove/add the
> per device proc files at the appropriate time." help in the case?
Yes. But since you can create the bonding device in the network
namespace you need it in, I don't see the point, of adding a code
path no one will test for 3 years at a time.
It seems easier to me to just not allow migration of bonding devices
and set peoples expectations a little lower. Especially given
the very complex user space interfaces.
On ther other hand if you want to write and test and generally own the
patch I will review it.
Eric
^ permalink raw reply
* Re: AF_BUS socket address family
From: Chris Friesen @ 2012-07-06 18:27 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Vincent Sanders, David Miller, netdev, linux-kernel
In-Reply-To: <alpine.LNX.2.01.1207052242450.2202@frira.zrqbmnf.qr>
> On Saturday 2012-06-30 01:12, Vincent Sanders wrote:
>> Firstly it is intended is an interprocess mechanism and not to rely on
>> a configured IP system, indeed one of its primary usages is to
>> provide mechanism for various tools to set up IP networking.
> Using IP as a localhost IPC is not uncommon (independent of
> software preferring AF_UNIX, if so available). Distro boot
> scripts have been running `ip addr add ::1/128 dev lo`
> all these years along.
>
> And now we suddently need a DBUS program just to configure
> IP-based localhost IPC? I can see the flaw in that.
>
I haven't tried it in a while but it used to be that you couldn't use IP
multicast on the "lo" device. Has that been fixed?
Chris
^ permalink raw reply
* [PATCH] smsc95xx: support ethtool get_regs
From: Émeric Vigier @ 2012-07-06 18:15 UTC (permalink / raw)
To: Steve Glendinning, steve glendinning; +Cc: netdev, Nancy Lin
In-Reply-To: <1291035348.223127.1341596173191.JavaMail.root@mail.savoirfairelinux.com>
From: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
Inspired by implementation in smsc911x.c and smsc9420.c
Tested on ARM/pandaboard rev A3
Signed-off-by: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
---
drivers/net/usb/smsc95xx.c | 37 +++++++++++++++++++++++++++++++++++++
1 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index b1112e7..bce14f6 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -578,6 +578,41 @@ static int smsc95xx_ethtool_set_eeprom(struct net_device *netdev,
return smsc95xx_write_eeprom(dev, ee->offset, ee->len, data);
}
+
+static int smsc95xx_ethtool_getregslen(struct net_device *dev)
+{
+ /* all smsc95xx registers plus all phy registers */
+ return COE_CR - ID_REV + 1 + 32 * sizeof(u32);
+}
+
+static void
+smsc95xx_ethtool_getregs(struct net_device *netdev, struct ethtool_regs *regs,
+ void *buf)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ unsigned int i, j = 0, retval;
+ u32 *data = buf;
+
+ netif_dbg(dev, hw, dev->net, "ethtool_getregs\n");
+
+ retval = smsc95xx_read_reg(dev, ID_REV, ®s->version);
+ if (retval < 0) {
+ netdev_warn(dev->net, "REGS: cannot read ID_REV\n");
+ return;
+ }
+
+ for (i = 0; i <= COE_CR; i += (sizeof(u32))) {
+ retval = smsc95xx_read_reg(dev, i, &data[j++]);
+ if (retval < 0) {
+ netdev_warn(dev->net, "REGS: cannot read reg[%x]\n", i);
+ return;
+ }
+ }
+
+ for (i = 0; i <= PHY_SPECIAL; i++)
+ data[j++] = smsc95xx_mdio_read(netdev, dev->mii.phy_id, i);
+}
+
static const struct ethtool_ops smsc95xx_ethtool_ops = {
.get_link = usbnet_get_link,
.nway_reset = usbnet_nway_reset,
@@ -589,6 +624,8 @@ static const struct ethtool_ops smsc95xx_ethtool_ops = {
.get_eeprom_len = smsc95xx_ethtool_get_eeprom_len,
.get_eeprom = smsc95xx_ethtool_get_eeprom,
.set_eeprom = smsc95xx_ethtool_set_eeprom,
+ .get_regs_len = smsc95xx_ethtool_getregslen,
+ .get_regs = smsc95xx_ethtool_getregs,
};
static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
--
1.7.5.4
Emeric
^ permalink raw reply related
* Re: [PATCH] gianfar: fix potential sk_wmem_alloc imbalance
From: Paul Gortmaker @ 2012-07-06 18:09 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, netdev, Manfred Rudigier, Claudiu Manoil, Jiajun Wu,
Andy Fleming
In-Reply-To: <1341524713.3265.41.camel@edumazet-glaptop>
[[PATCH] gianfar: fix potential sk_wmem_alloc imbalance] On 05/07/2012 (Thu 23:45) Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> commit db83d136d7f753 (gianfar: Fix missing sock reference when
> processing TX time stamps) added a potential sk_wmem_alloc imbalance
>
> If the new skb has a different truesize than old one, we can get a
> negative sk_wmem_alloc once new skb is orphaned at TX completion.
>
> Now we no longer early orphan skbs in dev_hard_start_xmit(), this
> probably can lead to fatal bugs.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Manfred Rudigier <manfred.rudigier@omicron.at>
> Cc: Claudiu Manoil <claudiu.manoil@freescale.com>
> Cc: Jiajun Wu <b06378@freescale.com>
> Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
> Cc: Andy Fleming <afleming@freescale.com>
> ---
>
> Note : I don't have the hardware and discovered this problem by code
> analysis. So please compile and run this patch before Acking it,
> thanks !
I can do that on Monday when I'm back in the office if nobody else has
already done it by then.
>
> BTW, dev->needed_headroom should be set to GMAC_FCB_LEN + GMAC_TXPAL_LEN
> to avoid reallocations...
Aside from the one line change at driver init, is there more to it than
that? More specifically, it currently does:
fcb_length = GMAC_FCB_LEN;
if (...timestamps...)
fcb_length = GMAC_FCB_LEN + GMAC_TXPAL_LEN;
if (... && (skb_headroom(skb) < fcb_length))
...
skb_new = skb_realloc_headroom(skb, fcb_length);
and I don't know the code well enough to know if setting the
needed_headroom value _guarantees_ the above fcb_length comparison
will always be false, and hence can be deleted. It kind of looks
like it via LL_RESERVED_SPACE, but I'm not 100% sure...
Thanks,
Paul.
--
>
> drivers/net/ethernet/freescale/gianfar.c | 7 +++----
> 1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
> index f2db8fc..ab1d80f 100644
> --- a/drivers/net/ethernet/freescale/gianfar.c
> +++ b/drivers/net/ethernet/freescale/gianfar.c
> @@ -2063,10 +2063,9 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
> return NETDEV_TX_OK;
> }
>
> - /* Steal sock reference for processing TX time stamps */
> - swap(skb_new->sk, skb->sk);
> - swap(skb_new->destructor, skb->destructor);
> - kfree_skb(skb);
> + if (skb->sk)
> + skb_set_owner_w(skb_new, skb->sk);
> + consume_skb(skb);
> skb = skb_new;
> }
>
>
>
^ permalink raw reply
* Re: Network namespace and bonding WARNING at fs/proc/generic.c remove_proc_entry
From: Dilip Daya @ 2012-07-06 18:01 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Eric W. Biederman, linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20120706170538.GA31679-7LNsyQBKDXoIagZqoN9o3w@public.gmane.org>
Hi Serge,
On Fri, 2012-07-06 at 17:05 +0000, Serge E. Hallyn wrote:
> Quoting Eric W. Biederman (ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org):
> > "Serge E. Hallyn" <serge-A9i7LUbDfNHQT0dZR+AlfA@public.gmane.org> writes:
> >
> > > Quoting Dilip Daya (dilip.daya-VXdhtT5mjnY@public.gmane.org):
> > >> Hi,
> > >>
> > >> I'd discussed the following with Serge Hallyn.
> > >>
> > >> => Environment based on 3.2.18 / x86_64 kernel.
> > >> => WARNING: at fs/proc/generic.c:808 remove_proc_entry+0xdb/0x21f()
> > >> => WARNING: at fs/proc/generic.c:849 remove_proc_entry+0x208/0x21f()
> > >
> > > Hi,
> > >
> > > thanks much for sending this. I'm still getting this error on
> > > 3.5.0-2-generic (today's ubuntu quantal kernel)
> > >
> > >> network namespace and bonding
> > >> -----------------------------
> > >>
> > >> * Migrate two phy nics from host to netns (netns0).
> > >> - ip link set ethX netns netns0
> > >>
> > >> * In host environment:
> > >> - load bonding module, /sbin/modprobe -v bonding mode=1 miimon=100
> > >> - /sys/class/net/bond0 exists.
> > >> - /proc/net/bonding/bond0 exists.
> > >> - /sys/class/net/bonding_masters has bond0.
> > >>
> > >> * Migrate bond0 to netns (netns0):
> > >> - ip link set bond0 netns netns0.
> > >>
> > >> * Within netns (netns0):
> > >> - /sys/class/net/bonding_masters is empty.
> > >> - /sys/class/net/bond0 exist.
> > >> - configure bond0 and ifenslave with two phy nics.
> > >> - /proc/net/bonding/bond0 does not exist within netns0, but does
> > >> exist in the host environment.
> > >> - /sys/class/net/bonding_masters is empty.
> > >
> > > mine is not empty, fwiw. However
> > >
> > >> - ping to remote end of bond0 works.
> > >>
> > >> * Within netns (netns0), flushing ethX and bondY:
> > >> - down bond0 and its phy nic interfaces:
> > >> - ip link set ... down
> > >> - ip addr flush dev [bond0 | eth#]
> > >> - deleting bond0, /sbin/ip link del dev bond0
> > >
> > > Yup I still get a remove_proc_entry WARNING at fs/proc/generic.c:808,
> > > which is the warning when (!de)
> >
> > It looks like Dilip is running an old kernel. There should have been
> > some version of /sys/class/net/bonding_masters in every network
> > namespace since sometime in 2009.
> >
> > >From the warning it looks like the proc files are being added/removed
> > to the wrong network namespace. So in one namespace we get an error
> > when we delete the moved device and in the other network namespace
> > we get an error when we remove the /proc/directory.
> >
> > An old kernel without proper network namespace support is the only
> > reason I can imagine someone would be moving an existing bond device
> > between network namespaces.
> >
> > If there are other reasons for wanting to move a bonding device between
> > network namespaces it is possible to catch the NETDEV_UNREGISTER and
> > NETDEV_REGISTER events to remove/add the per device proc files at the
> > appropriate time.
> >
> > However since moving bonding devices appears to be an unneded operation
> > let's just do things simply and forbid moving bonding devices between
> > network namespaces. Serge, Dilip can you two test the patch below
> > and see if it fixes the warnings.
> >
> > Eric
> >
> >
> > diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> > index 2ee8cf9..818ed64 100644
> > --- a/drivers/net/bonding/bond_main.c
> > +++ b/drivers/net/bonding/bond_main.c
> > @@ -4345,6 +4345,9 @@ static void bond_setup(struct net_device *bond_dev)
> > bond_dev->priv_flags |= IFF_BONDING;
> > bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
> >
> > + /* Don't allow bond devices to change network namespaces. */
> > + bond_dev->features |= NETIF_F_LOCAL;
>
> I believe this needs to be NETIF_F_NETNS_LOCAL. Test build still going with
> that change.
Correct, I made that change and rebuilt bonding driver:
# modinfo bonding | head
filename: /lib/modules/3.2.18-clim-3-amd64/kernel/drivers/net/bonding/bonding.ko
alias: rtnl-link-bond
author: Thomas Davis, tadavis-/3juihCSby0@public.gmane.org and many others
description: Ethernet Channel Bonding Driver, v3.7.1-netns
version: 3.7.1-netns
...
My results with the above bonding driver:
(1) Migrating bond0 from host to netns:
# ip link set bond0 netns netns0
RTNETLINK answers: Invalid argument
=> cannot migrate bond0 from host to netns.
=> No warnings.
(2) Loading bonding module in host environment and unloading bonding
module from within netns:
# modprobe -v -r bonding
#
rmmod /lib/modules/3.2.18-clim-3-amd64/kernel/drivers/net/bonding/bonding.ko
# lsmod | grep bond
<<< bonding module does not exist >>>
# ll /sys/class/net/
total 0
lrwxrwxrwx 1 root root 0 Jul 6 11:00 lo
-> ../../devices/virtual/net/lo/
lrwxrwxrwx 1 root root 0 Jul 6 11:00 eth7
-> ../../devices/pci0000:00/0000:00:05.0/0000:14:00.1/net/eth7/
lrwxrwxrwx 1 root root 0 Jul 6 11:00 eth6
-> ../../devices/pci0000:00/0000:00:05.0/0000:14:00.0/net/eth6/
=> No warnings.
-DilipD.
^ permalink raw reply
* Re: Network namespace and bonding WARNING at fs/proc/generic.c remove_proc_entry
From: Dilip Daya @ 2012-07-06 18:01 UTC (permalink / raw)
To: Eric W. Biederman
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <87ehopu3e5.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
Hi Eric,
On Thu, 2012-07-05 at 17:41 -0700, Eric W. Biederman wrote:
> "Serge E. Hallyn" <serge-A9i7LUbDfNHQT0dZR+AlfA@public.gmane.org> writes:
>
> > Quoting Dilip Daya (dilip.daya-VXdhtT5mjnY@public.gmane.org):
> >> Hi,
> >>
> >> I'd discussed the following with Serge Hallyn.
> >>
> >> => Environment based on 3.2.18 / x86_64 kernel.
> >> => WARNING: at fs/proc/generic.c:808 remove_proc_entry+0xdb/0x21f()
> >> => WARNING: at fs/proc/generic.c:849 remove_proc_entry+0x208/0x21f()
> >
> > Hi,
> >
> > thanks much for sending this. I'm still getting this error on
> > 3.5.0-2-generic (today's ubuntu quantal kernel)
> >
> >> network namespace and bonding
> >> -----------------------------
> >>
> >> * Migrate two phy nics from host to netns (netns0).
> >> - ip link set ethX netns netns0
> >>
> >> * In host environment:
> >> - load bonding module, /sbin/modprobe -v bonding mode=1 miimon=100
> >> - /sys/class/net/bond0 exists.
> >> - /proc/net/bonding/bond0 exists.
> >> - /sys/class/net/bonding_masters has bond0.
> >>
> >> * Migrate bond0 to netns (netns0):
> >> - ip link set bond0 netns netns0.
> >>
> >> * Within netns (netns0):
> >> - /sys/class/net/bonding_masters is empty.
> >> - /sys/class/net/bond0 exist.
> >> - configure bond0 and ifenslave with two phy nics.
> >> - /proc/net/bonding/bond0 does not exist within netns0, but does
> >> exist in the host environment.
> >> - /sys/class/net/bonding_masters is empty.
> >
> > mine is not empty, fwiw. However
> >
> >> - ping to remote end of bond0 works.
> >>
> >> * Within netns (netns0), flushing ethX and bondY:
> >> - down bond0 and its phy nic interfaces:
> >> - ip link set ... down
> >> - ip addr flush dev [bond0 | eth#]
> >> - deleting bond0, /sbin/ip link del dev bond0
> >
> > Yup I still get a remove_proc_entry WARNING at fs/proc/generic.c:808,
> > which is the warning when (!de)
>
> It looks like Dilip is running an old kernel. There should have been
> some version of /sys/class/net/bonding_masters in every network
> namespace since sometime in 2009.
>
> >From the warning it looks like the proc files are being added/removed
> to the wrong network namespace. So in one namespace we get an error
> when we delete the moved device and in the other network namespace
> we get an error when we remove the /proc/directory.
>
> An old kernel without proper network namespace support is the only
> reason I can imagine someone would be moving an existing bond device
> between network namespaces.
>
> If there are other reasons for wanting to move a bonding device between
> network namespaces it is possible to catch the NETDEV_UNREGISTER and
> NETDEV_REGISTER events to remove/add the per device proc files at the
> appropriate time.
We do need to move bonds between namespaces - because we require
physical interfaces in each namespace -- we don't want the overheads of
virtual interfaces, don't have the management infrastructure, and don't
want to manufacture fake mac addresses that would be required for
macvlan interfaces. Since the bonds are implicitly created in the host
namespace, the only way we know to get bonds directly into the
namespaces is to move them.
Would "NETDEV_UNREGISTER and NETDEV_REGISTER events to remove/add the
per device proc files at the appropriate time." help in the case?
-DilipD.
> However since moving bonding devices appears to be an unneded operation
> let's just do things simply and forbid moving bonding devices between
> network namespaces. Serge, Dilip can you two test the patch below
> and see if it fixes the warnings.
>
> Eric
>
>
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index 2ee8cf9..818ed64 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -4345,6 +4345,9 @@ static void bond_setup(struct net_device *bond_dev)
> bond_dev->priv_flags |= IFF_BONDING;
> bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
>
> + /* Don't allow bond devices to change network namespaces. */
> + bond_dev->features |= NETIF_F_LOCAL;
> +
> /* At first, we block adding VLANs. That's the only way to
> * prevent problems that occur when adding VLANs over an
> * empty bond. The block will be removed once non-challenged
^ permalink raw reply
* Re: [PATCH 4/4] asix: Add a new driver for the AX88172A
From: Ben Hutchings @ 2012-07-06 17:37 UTC (permalink / raw)
To: Christian Riesch
Cc: netdev, Oliver Neukum, Eric Dumazet, Allan Chou, Mark Lord,
Grant Grundler, Ming Lei, Michael Riesch
In-Reply-To: <1341574388-7464-5-git-send-email-christian.riesch@omicron.at>
On Fri, 2012-07-06 at 13:33 +0200, Christian Riesch wrote:
> The Asix AX88172A is a USB 2.0 Ethernet interface that supports both an
> internal PHY as well as an external PHY (connected via MII).
>
> This patch adds a driver for the AX88172A and provides support for
> both modes and supports phylib.
[...]
> +static int ax88172a_init_mdio(struct usbnet *dev)
> +{
> + struct ax88172a_private *priv =
> + (struct ax88172a_private *)dev->driver_priv;
> + int ret, i;
> +
> + priv->mdio = mdiobus_alloc();
> + if (!priv->mdio) {
> + dbg("Could not allocate MDIO bus");
> + return -1;
> + }
> +
> + priv->mdio->priv = (void *)dev;
> + priv->mdio->read = &asix_mdio_bus_read;
> + priv->mdio->write = &asix_mdio_bus_write;
> + priv->mdio->name = "Asix MDIO Bus";
> + snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "asix-%s",
> + dev_name(dev->net->dev.parent));
[...]
I think you need to ensure that the bus identifier is unique throughout
its lifetime, but net devices can be renamed and that could lead to a
collision. Perhaps you could use the ifindex or the USB device path
(though that might be too long).
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH next-next] ppp: change default for incoming protocol filter to NPMODE_DROP
From: Benjamin LaHaise @ 2012-07-06 17:28 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-ppp
In-Reply-To: <20120705.030027.655926012207641451.davem@davemloft.net>
On Thu, Jul 05, 2012 at 03:00:27AM -0700, David Miller wrote:
> As far as I can tell, this has been this way for a very long time.
>
> Therefore it is the applications responsibility to adjust the filters
> to suit their needs and we really can't make such adjustments to this
> behavior.
Okay. Clearing all the protocols the kernel may support in the future is a
bit expensive due to a lack of a way to get the protocols supported -- the
code would have to walk the entire protocol id space. How about the
following addition instead to provide a list of protocols to disable?
-ben
[PATCH net-next] ppp: add PPPIOCGPROTOS ioctl to get the list of protocols
At present there is no means for a userspace ppp implementation to get a
list of protocols supported by the kernel. Add an ioctl, PPPIOCGPROTOS to
get the protocol list array where [0] is the number of protocols in the
array.
Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 5c05572..daf50aa 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -565,6 +565,20 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
void __user *argp = (void __user *)arg;
int __user *p = argp;
+ if (cmd == PPPIOCGPROTOS) {
+ if (get_user(val, p))
+ return err;
+ if (val <= 0)
+ return -EINVAL;
+ if (NUM_NP < val)
+ val = NUM_NP;
+ if (put_user(val, p))
+ return err;
+ if (copy_to_user(p + 1, &npindex_to_proto, sizeof(int) * val))
+ return err;
+ return 0;
+ }
+
if (!pf)
return ppp_unattached_ioctl(current->nsproxy->net_ns,
pf, file, cmd, arg);
diff --git a/include/linux/ppp-ioctl.h b/include/linux/ppp-ioctl.h
index 2d9a885..d2cc304 100644
--- a/include/linux/ppp-ioctl.h
+++ b/include/linux/ppp-ioctl.h
@@ -81,6 +81,7 @@ struct pppol2tp_ioc_stats {
* Ioctl definitions.
*/
+#define PPPIOCGPROTOS _IOWR('t', 90, int) /* get protocol list array */
#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */
#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */
#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */
^ permalink raw reply related
* Re: [PATCH] ipv4: Avoid overhead when no custom FIB rules are installed.
From: Ben Hutchings @ 2012-07-06 17:19 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20120705.223142.2236039770560842377.davem@davemloft.net>
On Thu, 2012-07-05 at 22:31 -0700, David Miller wrote:
> If the user hasn't actually installed any custom rules, or fiddled
> with the default ones, don't go through the whole FIB rules layer.
>
> It's just pure overhead.
>
> Instead do what we do with CONFIG_IP_MULTIPLE_TABLES disabled, check
> the individual tables by hand, one by one.
>
> Also, move fib_num_tclassid_users into the ipv4 network namespace.
[...]
> --- a/net/ipv4/fib_rules.c
> +++ b/net/ipv4/fib_rules.c
[...]
> @@ -189,12 +190,14 @@ errout:
>
> static void fib4_rule_delete(struct fib_rule *rule)
> {
> + struct net *net = rule->fr_net;
> #ifdef CONFIG_IP_ROUTE_CLASSID
> struct fib4_rule *rule4 = (struct fib4_rule *) rule;
>
> if (rule4->tclassid)
> - fib_num_tclassid_users--;
> + net->ipv4.fib_num_tclassid_users--;
> #endif
> + net->ipv4.fib_has_custom_rules = true;
> }
[...]
Do you really mean to set fib_has_custom_rules = true on deletion?
Shouldn't it conditionally be set false? (Though the condition may be
too expensive to evaluate here without maintaining a separate counter.)
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: Network namespace and bonding WARNING at fs/proc/generic.c remove_proc_entry
From: Serge E. Hallyn @ 2012-07-06 17:05 UTC (permalink / raw)
To: Eric W. Biederman
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Dilip Daya, linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <87ehopu3e5.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
Quoting Eric W. Biederman (ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org):
> "Serge E. Hallyn" <serge-A9i7LUbDfNHQT0dZR+AlfA@public.gmane.org> writes:
>
> > Quoting Dilip Daya (dilip.daya-VXdhtT5mjnY@public.gmane.org):
> >> Hi,
> >>
> >> I'd discussed the following with Serge Hallyn.
> >>
> >> => Environment based on 3.2.18 / x86_64 kernel.
> >> => WARNING: at fs/proc/generic.c:808 remove_proc_entry+0xdb/0x21f()
> >> => WARNING: at fs/proc/generic.c:849 remove_proc_entry+0x208/0x21f()
> >
> > Hi,
> >
> > thanks much for sending this. I'm still getting this error on
> > 3.5.0-2-generic (today's ubuntu quantal kernel)
> >
> >> network namespace and bonding
> >> -----------------------------
> >>
> >> * Migrate two phy nics from host to netns (netns0).
> >> - ip link set ethX netns netns0
> >>
> >> * In host environment:
> >> - load bonding module, /sbin/modprobe -v bonding mode=1 miimon=100
> >> - /sys/class/net/bond0 exists.
> >> - /proc/net/bonding/bond0 exists.
> >> - /sys/class/net/bonding_masters has bond0.
> >>
> >> * Migrate bond0 to netns (netns0):
> >> - ip link set bond0 netns netns0.
> >>
> >> * Within netns (netns0):
> >> - /sys/class/net/bonding_masters is empty.
> >> - /sys/class/net/bond0 exist.
> >> - configure bond0 and ifenslave with two phy nics.
> >> - /proc/net/bonding/bond0 does not exist within netns0, but does
> >> exist in the host environment.
> >> - /sys/class/net/bonding_masters is empty.
> >
> > mine is not empty, fwiw. However
> >
> >> - ping to remote end of bond0 works.
> >>
> >> * Within netns (netns0), flushing ethX and bondY:
> >> - down bond0 and its phy nic interfaces:
> >> - ip link set ... down
> >> - ip addr flush dev [bond0 | eth#]
> >> - deleting bond0, /sbin/ip link del dev bond0
> >
> > Yup I still get a remove_proc_entry WARNING at fs/proc/generic.c:808,
> > which is the warning when (!de)
>
> It looks like Dilip is running an old kernel. There should have been
> some version of /sys/class/net/bonding_masters in every network
> namespace since sometime in 2009.
>
> >From the warning it looks like the proc files are being added/removed
> to the wrong network namespace. So in one namespace we get an error
> when we delete the moved device and in the other network namespace
> we get an error when we remove the /proc/directory.
>
> An old kernel without proper network namespace support is the only
> reason I can imagine someone would be moving an existing bond device
> between network namespaces.
>
> If there are other reasons for wanting to move a bonding device between
> network namespaces it is possible to catch the NETDEV_UNREGISTER and
> NETDEV_REGISTER events to remove/add the per device proc files at the
> appropriate time.
>
> However since moving bonding devices appears to be an unneded operation
> let's just do things simply and forbid moving bonding devices between
> network namespaces. Serge, Dilip can you two test the patch below
> and see if it fixes the warnings.
>
> Eric
>
>
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index 2ee8cf9..818ed64 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -4345,6 +4345,9 @@ static void bond_setup(struct net_device *bond_dev)
> bond_dev->priv_flags |= IFF_BONDING;
> bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
>
> + /* Don't allow bond devices to change network namespaces. */
> + bond_dev->features |= NETIF_F_LOCAL;
I believe this needs to be NETIF_F_NETNS_LOCAL. Test build still going with
that change.
> +
> /* At first, we block adding VLANs. That's the only way to
> * prevent problems that occur when adding VLANs over an
> * empty bond. The block will be removed once non-challenged
^ permalink raw reply
* Re: [net-next RFC V5 0/5] Multiqueue virtio-net
From: Rick Jones @ 2012-07-06 16:23 UTC (permalink / raw)
To: Jason Wang
Cc: krkumar2, habanero, mashirle, kvm, mst, netdev, linux-kernel,
virtualization, edumazet, tahm, jwhan, davem, sri
In-Reply-To: <4FF696C9.5070907@redhat.com>
On 07/06/2012 12:42 AM, Jason Wang wrote:
> I'm not expert of tcp, but looks like the changes are reasonable:
> - we can do full-sized TSO check in tcp_tso_should_defer() only for
> westwood, according to tcp westwood
> - run tcp_tso_should_defer for tso_segs = 1 when tso is enabled.
I'm sure Eric and David will weigh-in on the TCP change. My initial
inclination would have been to say "well, if multiqueue is draining
faster, that means ACKs come-back faster, which means the "race" between
more data being queued by netperf and ACKs will go more to the ACKs
which means the segments being sent will be smaller - as TCP_NODELAY is
not set, the Nagle algorithm is in force, which means once there is data
outstanding on the connection, no more will be sent until either the
outstanding data is ACKed, or there is an accumulation of > MSS worth of
data to send.
>> Also, how are you combining the concurrent netperf results? Are you
>> taking sums of what netperf reports, or are you gathering statistics
>> outside of netperf?
>>
>
> The throughput were just sumed from netperf result like what netperf
> manual suggests. The cpu utilization were measured by mpstat.
Which mechanism to address skew error? The netperf manual describes
more than one:
http://www.netperf.org/svn/netperf2/trunk/doc/netperf.html#Using-Netperf-to-Measure-Aggregate-Performance
Personally, my preference these days is to use the "demo mode" method of
aggregate results as it can be rather faster than (ab)using the
confidence intervals mechanism, which I suspect may not really scale all
that well to large numbers of concurrent netperfs.
I also tend to use the --enable-burst configure option to allow me to
minimize the number of concurrent netperfs in the first place. Set
TCP_NODELAY (the test-specific -D option) and then have several
transactions outstanding at one time (test-specific -b option with a
number of additional in-flight transactions).
This is expressed in the runemomniaggdemo.sh script:
http://www.netperf.org/svn/netperf2/trunk/doc/examples/runemomniaggdemo.sh
which uses the find_max_burst.sh script:
http://www.netperf.org/svn/netperf2/trunk/doc/examples/find_max_burst.sh
to pick the burst size to use in the concurrent netperfs, the results of
which can be post-processed with:
http://www.netperf.org/svn/netperf2/trunk/doc/examples/post_proc.py
The nice feature of using the "demo mode" mechanism is when it is
coupled with systems with reasonably synchronized clocks (eg NTP) it can
be used for many-to-many testing in addition to one-to-many testing
(which cannot be dealt with by the confidence interval method of dealing
with skew error)
>> A single instance TCP_RR test would help confirm/refute any
>> non-trivial change in (effective) path length between the two cases.
>>
>
> Yes, I would test this thanks.
Excellent.
happy benchmarking,
rick jones
^ permalink raw reply
* Re: [RFC PATCH] bridge: netfilter: fix skb->nf_bridge NULL panic in br_nf_forward_finish
From: Lin Ming @ 2012-07-06 15:37 UTC (permalink / raw)
To: Eric Dumazet
Cc: Massimo Cetra, netdev, Stephen Hemminger, David S. Miller,
Julian Anastasov
In-Reply-To: <1341587206.3265.696.camel@edumazet-glaptop>
On Fri, Jul 6, 2012 at 11:06 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Fri, 2012-07-06 at 22:19 +0800, Lin Ming wrote:
>> I can reproduce similiar panic with 3.5-rc5 kernel as Massimo reported at:
>> http://marc.info/?l=linux-netdev&m=134089242113979&w=2
>>
>> The steps to reproduce as follow,
>>
>> 1. On Host1, setup brige br0(192.168.1.106)
>> 2. Boot a kvm guest(192.168.1.105) on Host1 and start httpd
>> 3. Start IPVS service on Host1
>> ipvsadm -A -t 192.168.1.106:80 -s rr
>> ipvsadm -a -t 192.168.1.106:80 -r 192.168.1.105:80 -m
>> 4. Run apache benchmark on Host2(192.168.1.101)
>> ab -n 1000 http://192.168.1.106/
>>
>> The panic happened in br_nf_forward_finish because skb->nf_bridge is NULL.
>> skb->nf_bridge is set to NULL in ip_vs_reply4 hook.
>>
>> br_nf_forward_ip():
>> NF_HOOK(pf, NF_INET_FORWARD, skb, brnf_get_logical_dev(skb, in), parent,
>> br_nf_forward_finish);
>>
>> This calls IPVS hook ip_vs_reply4.
>>
>> ip_vs_reply4
>> ip_vs_out
>> handle_response
>> ip_vs_notrack
>> nf_reset()
>> {
>> skb->nf_bridge = NULL;
>> }
>>
>> This patch added skb->nf_bridge check in br_nf_forward_finish and the panic gone.
>> But I am really not sure if this is the right fix.
>> Please help to review.
>>
>> The panic log attached.
> ...
>> Signed-off-by: Lin Ming <mlin@ss.pku.edu.cn>
>> ---
>> net/bridge/br_netfilter.c | 2 +-
>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
>> index e41456b..10da415 100644
>> --- a/net/bridge/br_netfilter.c
>> +++ b/net/bridge/br_netfilter.c
>> @@ -719,7 +719,7 @@ static int br_nf_forward_finish(struct sk_buff *skb)
>> struct nf_bridge_info *nf_bridge = skb->nf_bridge;
>> struct net_device *in;
>>
>> - if (!IS_ARP(skb) && !IS_VLAN_ARP(skb)) {
>> + if (!IS_ARP(skb) && !IS_VLAN_ARP(skb) && nf_bridge) {
>> in = nf_bridge->physindev;
>> if (nf_bridge->mask & BRNF_PKT_TYPE) {
>> skb->pkt_type = PACKET_OTHERHOST;
>
> So after your patch we have the code in the else clause :
>
> } else {
> in = *((struct net_device **)(skb->cb));
> }
>
> But do we really have a "struct net_device" pointer stored in skb->cb[]
> at this stage ?
>
> AFAIK this is set only for ARP_FORWARD (br_nf_forward_arp() line 838 :
> *d = (struct net_device *)in;),
> not in br_nf_forward_ip()
>
> If we have garbage instead, we can have other bugs later...
You are right.
The fundamental problem maybe in IPVS hook ip_vs_reply4 ......
^ permalink raw reply
* Re: [PATCH v2 net-next 2/2] r8169: support RTL8168G
From: Joe Perches @ 2012-07-06 15:37 UTC (permalink / raw)
To: Francois Romieu; +Cc: Hayes Wang, netdev, linux-kernel
In-Reply-To: <20120706152046.GB6981@electric-eye.fr.zoreil.com>
On Fri, 2012-07-06 at 17:20 +0200, Francois Romieu wrote:
> Joe Perches <joe@perches.com> :
> [...]
> > This pattern is used a couple more times.
> > There's no failure handling either.
>
> I can do something for the initialize path. Other than that it's mostly
> deeply burried hardware failure so I'd rather concentrate a bit on
> current problem reports.
>
> This series already took me a bit further than expected (see below).
Allez Francois.
When you take up a suggestion, you really go with it.
^ permalink raw reply
* Re: [PATCH v2 net-next 2/2] r8169: support RTL8168G
From: Francois Romieu @ 2012-07-06 15:20 UTC (permalink / raw)
To: Joe Perches; +Cc: Hayes Wang, netdev, linux-kernel
In-Reply-To: <1341449507.2058.6.camel@joe2Laptop>
[-- Attachment #1: Type: text/plain, Size: 22030 bytes --]
Joe Perches <joe@perches.com> :
[...]
> This pattern is used a couple more times.
> There's no failure handling either.
I can do something for the initialize path. Other than that it's mostly
deeply burried hardware failure so I'd rather concentrate a bit on
current problem reports.
This series already took me a bit further than expected (see below).
> Maybe use a macro with RTL_R8/32, register and test?
Here is what I came up with. Completely untested. Attached patches #1 and
#2 should be applied on top of the previous patch beforehand.
[PATCH 3/3] r8169: abstract out loop conditions.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/realtek/r8169.c | 460 +++++++++++++++++-----------------
1 file changed, 225 insertions(+), 235 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 0759c76..4f350fc 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -844,47 +844,113 @@ static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
}
}
+struct rtl_cond {
+ bool (*check)(struct rtl8169_private *);
+ const char *msg;
+};
+
+static void rtl_udelay(unsigned int d)
+{
+ udelay(d);
+}
+
+static bool rtl_loop_wait(struct rtl8169_private *tp, const struct rtl_cond *c,
+ void (*delay)(unsigned int), unsigned int d, int n,
+ bool high)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ delay(d);
+ if (c->check(tp) == high)
+ return true;
+ }
+ netif_err(tp, drv, tp->dev, c->msg);
+ return false;
+}
+
+static bool rtl_udelay_loop_wait_high(struct rtl8169_private *tp,
+ const struct rtl_cond *c,
+ unsigned int d, int n)
+{
+ return rtl_loop_wait(tp, c, rtl_udelay, d, n, true);
+}
+
+static bool rtl_udelay_loop_wait_low(struct rtl8169_private *tp,
+ const struct rtl_cond *c,
+ unsigned int d, int n)
+{
+ return rtl_loop_wait(tp, c, rtl_udelay, d, n, false);
+}
+
+static bool rtl_msleep_loop_wait_high(struct rtl8169_private *tp,
+ const struct rtl_cond *c,
+ unsigned int d, int n)
+{
+ return rtl_loop_wait(tp, c, msleep, d, n, true);
+}
+
+static bool rtl_msleep_loop_wait_low(struct rtl8169_private *tp,
+ const struct rtl_cond *c,
+ unsigned int d, int n)
+{
+ return rtl_loop_wait(tp, c, msleep, d, n, false);
+}
+
+#define DECLARE_RTL_COND(name) \
+static bool name ## _check(struct rtl8169_private *); \
+ \
+static const struct rtl_cond name = { \
+ .check = name ## _check, \
+ .msg = #name \
+}; \
+ \
+static bool name ## _check(struct rtl8169_private *tp)
+
+DECLARE_RTL_COND(rtl_ocpar_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(OCPAR) & OCPAR_FLAG;
+}
+
static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
{
void __iomem *ioaddr = tp->mmio_addr;
- int i;
RTL_W32(OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
- for (i = 0; i < 20; i++) {
- udelay(100);
- if (RTL_R32(OCPAR) & OCPAR_FLAG)
- break;
- }
- return RTL_R32(OCPDR);
+
+ return rtl_udelay_loop_wait_high(tp, &rtl_ocpar_cond, 100, 20) ?
+ RTL_R32(OCPDR) : ~0;
}
static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data)
{
void __iomem *ioaddr = tp->mmio_addr;
- int i;
RTL_W32(OCPDR, data);
RTL_W32(OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
- for (i = 0; i < 20; i++) {
- udelay(100);
- if ((RTL_R32(OCPAR) & OCPAR_FLAG) == 0)
- break;
- }
+
+ rtl_udelay_loop_wait_low(tp, &rtl_ocpar_cond, 100, 20);
+}
+
+DECLARE_RTL_COND(rtl_eriar_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(ERIAR) & ERIAR_FLAG;
}
static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd)
{
void __iomem *ioaddr = tp->mmio_addr;
- int i;
RTL_W8(ERIDR, cmd);
RTL_W32(ERIAR, 0x800010e8);
msleep(2);
- for (i = 0; i < 5; i++) {
- udelay(100);
- if (!(RTL_R32(ERIAR) & ERIAR_FLAG))
- break;
- }
+
+ if (!rtl_udelay_loop_wait_low(tp, &rtl_eriar_cond, 100, 5))
+ return;
ocp_write(tp, 0x1, 0x30, 0x00000001);
}
@@ -898,36 +964,27 @@ static u16 rtl8168_get_ocp_reg(struct rtl8169_private *tp)
return (tp->mac_version == RTL_GIGA_MAC_VER_31) ? 0xb8 : 0x10;
}
-static void rtl8168_driver_start(struct rtl8169_private *tp)
+DECLARE_RTL_COND(rtl_ocp_read_cond)
{
u16 reg;
- int i;
-
- rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);
reg = rtl8168_get_ocp_reg(tp);
- for (i = 0; i < 10; i++) {
- msleep(10);
- if (ocp_read(tp, 0x0f, reg) & 0x00000800)
- break;
- }
+ return ocp_read(tp, 0x0f, reg) & 0x00000800;
}
-static void rtl8168_driver_stop(struct rtl8169_private *tp)
+static void rtl8168_driver_start(struct rtl8169_private *tp)
{
- u16 reg;
- int i;
+ rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);
- rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP);
+ rtl_msleep_loop_wait_high(tp, &rtl_ocp_read_cond, 10, 10);
+}
- reg = rtl8168_get_ocp_reg(tp);
+static void rtl8168_driver_stop(struct rtl8169_private *tp)
+{
+ rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP);
- for (i = 0; i < 10; i++) {
- msleep(10);
- if ((ocp_read(tp, 0x0f, reg) & 0x00000800) == 0)
- break;
- }
+ rtl_msleep_loop_wait_low(tp, &rtl_ocp_read_cond, 10, 10);
}
static int r8168dp_check_dash(struct rtl8169_private *tp)
@@ -946,42 +1003,36 @@ static bool rtl_ocp_reg_failure(struct rtl8169_private *tp, u32 reg)
return false;
}
+DECLARE_RTL_COND(rtl_ocp_gphy_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(GPHY_OCP) & OCPAR_FLAG;
+}
+
static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
{
void __iomem *ioaddr = tp->mmio_addr;
- int i;
if (rtl_ocp_reg_failure(tp, reg))
return;
RTL_W32(GPHY_OCP, OCPAR_FLAG | (reg << 15) | data);
- for (i = 0; i < 10; i++) {
- udelay(25);
- if (!(RTL_R32(GPHY_OCP) & OCPAR_FLAG))
- break;
- }
+ rtl_udelay_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10);
}
static u16 r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg)
{
void __iomem *ioaddr = tp->mmio_addr;
- u32 data;
- int i;
if (rtl_ocp_reg_failure(tp, reg))
return 0;
RTL_W32(GPHY_OCP, reg << 15);
- for (i = 0; i < 10; i++) {
- udelay(25);
- data = RTL_R32(GPHY_OCP);
- if (data & OCPAR_FLAG)
- break;
- }
-
- return (u16)(data & 0xffff);
+ return rtl_udelay_loop_wait_high(tp, &rtl_ocp_gphy_cond, 25, 10) ?
+ (RTL_R32(GPHY_OCP) & 0xffff) : ~0;
}
static void rtl_w1w0_phy_ocp(struct rtl8169_private *tp, int reg, int p, int m)
@@ -992,42 +1043,36 @@ static void rtl_w1w0_phy_ocp(struct rtl8169_private *tp, int reg, int p, int m)
r8168_phy_ocp_write(tp, reg, (val | p) & ~m);
}
+DECLARE_RTL_COND(rtl_ocpdr_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(OCPDR) & OCPAR_FLAG;
+}
+
static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
{
void __iomem *ioaddr = tp->mmio_addr;
- int i;
if (rtl_ocp_reg_failure(tp, reg))
return;
RTL_W32(OCPDR, OCPAR_FLAG | (reg << 15) | data);
- for (i = 0; i < 10; i++) {
- udelay(25);
- if (!(RTL_R32(OCPDR) & OCPAR_FLAG))
- break;
- }
+ rtl_udelay_loop_wait_low(tp, &rtl_ocpdr_cond, 25, 10);
}
static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg)
{
void __iomem *ioaddr = tp->mmio_addr;
- u32 data;
- int i;
if (rtl_ocp_reg_failure(tp, reg))
return 0;
RTL_W32(OCPDR, reg << 15);
- for (i = 0; i < 10; i++) {
- udelay(25);
- data = RTL_R32(OCPDR);
- if (data & OCPAR_FLAG)
- break;
- }
-
- return (u16)(data & 0xffff);
+ return rtl_udelay_loop_wait_high(tp, &rtl_ocpdr_cond, 25, 10) ?
+ RTL_R32(OCPDR) : ~0;
}
#define OCP_STD_PHY_BASE 0xa400
@@ -1053,23 +1098,22 @@ static int r8168g_mdio_read(struct rtl8169_private *tp, int reg_addr)
return r8168_phy_ocp_read(tp, tp->ocp_base + reg_addr * 2);
}
+DECLARE_RTL_COND(rtl_phyar_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(PHYAR) & 0x80000000;
+}
+
static
void r8169_mdio_write(struct rtl8169_private *tp, int reg_addr, int value)
{
void __iomem *ioaddr = tp->mmio_addr;
- int i;
RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff));
- for (i = 20; i > 0; i--) {
- /*
- * Check if the RTL8169 has completed writing to the specified
- * MII register.
- */
- if (!(RTL_R32(PHYAR) & 0x80000000))
- break;
- udelay(25);
- }
+ rtl_udelay_loop_wait_low(tp, &rtl_phyar_cond, 25, 20);
+
/*
* According to hardware specs a 20us delay is required after write
* complete indication, but before sending next command.
@@ -1080,21 +1124,13 @@ void r8169_mdio_write(struct rtl8169_private *tp, int reg_addr, int value)
static int r8169_mdio_read(struct rtl8169_private *tp, int reg_addr)
{
void __iomem *ioaddr = tp->mmio_addr;
- int i, value = -1;
+ int value;
RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16);
- for (i = 20; i > 0; i--) {
- /*
- * Check if the RTL8169 has completed retrieving data from
- * the specified MII register.
- */
- if (RTL_R32(PHYAR) & 0x80000000) {
- value = RTL_R32(PHYAR) & 0xffff;
- break;
- }
- udelay(25);
- }
+ value = rtl_udelay_loop_wait_high(tp, &rtl_phyar_cond, 25, 20) ?
+ RTL_R32(PHYAR) & 0xffff : ~0;
+
/*
* According to hardware specs a 20us delay is required after read
* complete indication, but before sending next command.
@@ -1107,17 +1143,12 @@ static int r8169_mdio_read(struct rtl8169_private *tp, int reg_addr)
static void r8168dp_1_mdio_access(struct rtl8169_private *tp, int reg, u32 data)
{
void __iomem *ioaddr = tp->mmio_addr;
- int i;
RTL_W32(OCPDR, data | ((reg & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT));
RTL_W32(OCPAR, OCPAR_GPHY_WRITE_CMD);
RTL_W32(EPHY_RXER_NUM, 0);
- for (i = 0; i < 100; i++) {
- mdelay(1);
- if (!(RTL_R32(OCPAR) & OCPAR_FLAG))
- break;
- }
+ rtl_udelay_loop_wait_low(tp, &rtl_ocpar_cond, 1000, 100);
}
static void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg, int value)
@@ -1129,7 +1160,6 @@ static void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg, int value)
static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg_addr)
{
void __iomem *ioaddr = tp->mmio_addr;
- int i;
r8168dp_1_mdio_access(tp, reg_addr, OCPDR_READ_CMD);
@@ -1137,13 +1167,8 @@ static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg_addr)
RTL_W32(OCPAR, OCPAR_GPHY_READ_CMD);
RTL_W32(EPHY_RXER_NUM, 0);
- for (i = 0; i < 100; i++) {
- mdelay(1);
- if (RTL_R32(OCPAR) & OCPAR_FLAG)
- break;
- }
-
- return RTL_R32(OCPDR) & OCPDR_DATA_MASK;
+ return rtl_udelay_loop_wait_high(tp, &rtl_ocpar_cond, 1000, 100) ?
+ RTL_R32(OCPDR) & OCPDR_DATA_MASK : ~0;
}
#define R8168DP_1_MDIO_ACCESS_BIT 0x00020000
@@ -1221,74 +1246,55 @@ static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
return rtl_readphy(tp, location);
}
+DECLARE_RTL_COND(rtl_ephyar_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(EPHYAR) & EPHYAR_FLAG;
+}
+
static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value)
{
void __iomem *ioaddr = tp->mmio_addr;
- unsigned int i;
RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
(reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
- for (i = 0; i < 100; i++) {
- if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG))
- break;
- udelay(10);
- }
+ rtl_udelay_loop_wait_low(tp, &rtl_ephyar_cond, 10, 100);
+
+ udelay(10);
}
static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr)
{
void __iomem *ioaddr = tp->mmio_addr;
- u16 value = 0xffff;
- unsigned int i;
RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
- for (i = 0; i < 100; i++) {
- if (RTL_R32(EPHYAR) & EPHYAR_FLAG) {
- value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK;
- break;
- }
- udelay(10);
- }
-
- return value;
+ return rtl_udelay_loop_wait_high(tp, &rtl_ephyar_cond, 10, 100) ?
+ RTL_R32(EPHYAR) & EPHYAR_DATA_MASK : ~0;
}
static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask,
u32 val, int type)
{
void __iomem *ioaddr = tp->mmio_addr;
- unsigned int i;
BUG_ON((addr & 3) || (mask == 0));
RTL_W32(ERIDR, val);
RTL_W32(ERIAR, ERIAR_WRITE_CMD | type | mask | addr);
- for (i = 0; i < 100; i++) {
- if (!(RTL_R32(ERIAR) & ERIAR_FLAG))
- break;
- udelay(100);
- }
+ rtl_udelay_loop_wait_low(tp, &rtl_eriar_cond, 100, 100);
}
static u32 rtl_eri_read(struct rtl8169_private *tp, int addr, int type)
{
void __iomem *ioaddr = tp->mmio_addr;
- u32 value = ~0x00;
- unsigned int i;
RTL_W32(ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr);
- for (i = 0; i < 100; i++) {
- if (RTL_R32(ERIAR) & ERIAR_FLAG) {
- value = RTL_R32(ERIDR);
- break;
- }
- udelay(100);
- }
-
- return value;
+ return rtl_udelay_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ?
+ RTL_R32(ERIDR) : ~0;
}
static void rtl_w1w0_eri(struct rtl8169_private *tp, int addr, u32 mask, u32 p,
@@ -1315,23 +1321,21 @@ static void rtl_write_exgmac_batch(struct rtl8169_private *tp,
}
}
+DECLARE_RTL_COND(rtl_efusear_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(EFUSEAR) & EFUSEAR_FLAG;
+}
+
static u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr)
{
void __iomem *ioaddr = tp->mmio_addr;
- u8 value = 0xff;
- unsigned int i;
RTL_W32(EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT);
- for (i = 0; i < 300; i++) {
- if (RTL_R32(EFUSEAR) & EFUSEAR_FLAG) {
- value = RTL_R32(EFUSEAR) & EFUSEAR_DATA_MASK;
- break;
- }
- udelay(100);
- }
-
- return value;
+ return rtl_udelay_loop_wait_high(tp, &rtl_efusear_cond, 100, 300) ?
+ RTL_R32(EFUSEAR) & EFUSEAR_DATA_MASK : ~0;
}
static u16 rtl_get_events(struct rtl8169_private *tp)
@@ -1938,6 +1942,13 @@ static int rtl8169_get_sset_count(struct net_device *dev, int sset)
}
}
+DECLARE_RTL_COND(rtl_counters_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(CounterAddrLow) & CounterDump;
+}
+
static void rtl8169_update_counters(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -1946,7 +1957,6 @@ static void rtl8169_update_counters(struct net_device *dev)
struct rtl8169_counters *counters;
dma_addr_t paddr;
u32 cmd;
- int wait = 1000;
/*
* Some chips are unable to dump tally counters when the receiver
@@ -1964,13 +1974,8 @@ static void rtl8169_update_counters(struct net_device *dev)
RTL_W32(CounterAddrLow, cmd);
RTL_W32(CounterAddrLow, cmd | CounterDump);
- while (wait--) {
- if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) {
- memcpy(&tp->counters, counters, sizeof(*counters));
- break;
- }
- udelay(10);
- }
+ if (rtl_udelay_loop_wait_low(tp, &rtl_counters_cond, 10, 1000))
+ memcpy(&tp->counters, counters, sizeof(*counters));
RTL_W32(CounterAddrLow, 0);
RTL_W32(CounterAddrHigh, 0);
@@ -3662,18 +3667,16 @@ static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
free_netdev(dev);
}
+DECLARE_RTL_COND(rtl_phy_reset_cond)
+{
+ return tp->phy_reset_pending(tp);
+}
+
static void rtl8169_phy_reset(struct net_device *dev,
struct rtl8169_private *tp)
{
- unsigned int i;
-
tp->phy_reset_enable(tp);
- for (i = 0; i < 100; i++) {
- if (!tp->phy_reset_pending(tp))
- return;
- msleep(1);
- }
- netif_err(tp, link, dev, "PHY reset failed\n");
+ rtl_msleep_loop_wait_low(tp, &rtl_phy_reset_cond, 1, 100);
}
static bool rtl_tbi_enabled(struct rtl8169_private *tp)
@@ -4307,20 +4310,20 @@ static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp)
}
}
+DECLARE_RTL_COND(rtl_chipcmd_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R8(ChipCmd) & CmdReset;
+}
+
static void rtl_hw_reset(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
- int i;
- /* Soft reset the chip. */
RTL_W8(ChipCmd, CmdReset);
- /* Check that the chip has finished the reset. */
- for (i = 0; i < 100; i++) {
- if ((RTL_R8(ChipCmd) & CmdReset) == 0)
- break;
- udelay(100);
- }
+ rtl_udelay_loop_wait_low(tp, &rtl_chipcmd_cond, 100, 100);
}
static void rtl_request_uncached_firmware(struct rtl8169_private *tp)
@@ -4374,6 +4377,20 @@ static void rtl_rx_close(struct rtl8169_private *tp)
RTL_W32(RxConfig, RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK);
}
+DECLARE_RTL_COND(rtl_npq_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R8(TxPoll) & NPQ;
+}
+
+DECLARE_RTL_COND(rtl_txcfg_empty_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(TxConfig) & TXCFG_EMPTY;
+}
+
static void rtl8169_hw_reset(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
@@ -4386,8 +4403,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
tp->mac_version == RTL_GIGA_MAC_VER_28 ||
tp->mac_version == RTL_GIGA_MAC_VER_31) {
- while (RTL_R8(TxPoll) & NPQ)
- udelay(20);
+ rtl_udelay_loop_wait_low(tp, &rtl_npq_cond, 20, 42*42);
} else if (tp->mac_version == RTL_GIGA_MAC_VER_34 ||
tp->mac_version == RTL_GIGA_MAC_VER_35 ||
tp->mac_version == RTL_GIGA_MAC_VER_36 ||
@@ -4396,8 +4412,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
tp->mac_version == RTL_GIGA_MAC_VER_41 ||
tp->mac_version == RTL_GIGA_MAC_VER_38) {
RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq);
- while (!(RTL_R32(TxConfig) & TXCFG_EMPTY))
- udelay(100);
+ rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
} else {
RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq);
udelay(100);
@@ -4608,7 +4623,7 @@ static void rtl_csi_write(struct rtl8169_private *tp, int addr, int value)
static u32 rtl_csi_read(struct rtl8169_private *tp, int addr)
{
- return tp->csi_ops.read ? tp->csi_ops.read(tp, addr) :~0;
+ return tp->csi_ops.read ? tp->csi_ops.read(tp, addr) : ~0;
}
static void rtl_csi_access_enable(struct rtl8169_private *tp, u32 bits)
@@ -4629,77 +4644,56 @@ static void rtl_csi_access_enable_2(struct rtl8169_private *tp)
rtl_csi_access_enable(tp, 0x27000000);
}
+DECLARE_RTL_COND(rtl_csiar_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(CSIAR) & CSIAR_FLAG;
+}
+
static void r8169_csi_write(struct rtl8169_private *tp, int addr, int value)
{
void __iomem *ioaddr = tp->mmio_addr;
- unsigned int i;
RTL_W32(CSIDR, value);
RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
- for (i = 0; i < 100; i++) {
- if (!(RTL_R32(CSIAR) & CSIAR_FLAG))
- break;
- udelay(10);
- }
+ rtl_udelay_loop_wait_low(tp, &rtl_csiar_cond, 10, 100);
}
static u32 r8169_csi_read(struct rtl8169_private *tp, int addr)
{
void __iomem *ioaddr = tp->mmio_addr;
- u32 value = ~0x00;
- unsigned int i;
RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) |
CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
- for (i = 0; i < 100; i++) {
- if (RTL_R32(CSIAR) & CSIAR_FLAG) {
- value = RTL_R32(CSIDR);
- break;
- }
- udelay(10);
- }
-
- return value;
+ return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ?
+ RTL_R32(CSIDR) : ~0;
}
static void r8402_csi_write(struct rtl8169_private *tp, int addr, int value)
{
void __iomem *ioaddr = tp->mmio_addr;
- unsigned int i;
RTL_W32(CSIDR, value);
RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT |
CSIAR_FUNC_NIC);
- for (i = 0; i < 100; i++) {
- if (!(RTL_R32(CSIAR) & CSIAR_FLAG))
- break;
- udelay(10);
- }
+ rtl_udelay_loop_wait_low(tp, &rtl_csiar_cond, 10, 100);
}
static u32 r8402_csi_read(struct rtl8169_private *tp, int addr)
{
void __iomem *ioaddr = tp->mmio_addr;
- u32 value = ~0x00;
- unsigned int i;
RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) | CSIAR_FUNC_NIC |
CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
- for (i = 0; i < 100; i++) {
- if (RTL_R32(CSIAR) & CSIAR_FLAG) {
- value = RTL_R32(CSIDR);
- break;
- }
- udelay(10);
- }
-
- return value;
+ return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ?
+ RTL_R32(CSIDR) : ~0;
}
static void __devinit rtl_init_csi_ops(struct rtl8169_private *tp)
@@ -6731,17 +6725,18 @@ static unsigned rtl_try_msi(struct rtl8169_private *tp,
return msi;
}
-#define RTL_LOOP_MAX 10000
+DECLARE_RTL_COND(rtl_link_list_ready_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
-static void rtl_mcu_wait_list_ready(void __iomem *ioaddr)
+ return RTL_R8(MCU) & LINK_LIST_RDY;
+}
+
+DECLARE_RTL_COND(rtl_rxtx_empty_cond)
{
- int i;
+ void __iomem *ioaddr = tp->mmio_addr;
- for (i = 0; i < RTL_LOOP_MAX; i++) {
- if (RTL_R8(MCU) & LINK_LIST_RDY)
- return;
- udelay(100);
- }
+ return (RTL_R8(MCU) & RXTX_EMPTY) == RXTX_EMPTY;
}
#define PLOP 0xe8de
@@ -6750,21 +6745,14 @@ static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
u32 data;
- int i;
RTL_W32(MISC, RTL_R32(MISC) | RXDV_GATED_EN);
- for (i = 0; i < RTL_LOOP_MAX; i++) {
- if (RTL_R32(TxConfig) & TXCFG_EMPTY)
- break;
- udelay(100);
- }
+ if (!rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42))
+ return;
- for (i = 0; i < RTL_LOOP_MAX; i++) {
- if ((RTL_R8(MCU) & RXTX_EMPTY) == RXTX_EMPTY)
- break;
- udelay(100);
- }
+ if (!rtl_udelay_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42))
+ return;
RTL_W8(ChipCmd, RTL_R8(ChipCmd) & ~(CmdTxEnb | CmdRxEnb));
msleep(1);
@@ -6774,13 +6762,15 @@ static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp)
data &= ~(1 << 14);
r8168_mac_ocp_write(ioaddr, PLOP, data);
- rtl_mcu_wait_list_ready(ioaddr);
+ if (!rtl_udelay_loop_wait_high(tp, &rtl_link_list_ready_cond, 100, 42))
+ return;
data = r8168_mac_ocp_read(ioaddr, PLOP);
data |= (1 << 15);
r8168_mac_ocp_write(ioaddr, PLOP, data);
- rtl_mcu_wait_list_ready(ioaddr);
+ if (!rtl_udelay_loop_wait_high(tp, &rtl_link_list_ready_cond, 100, 42))
+ return;
}
static void __devinit rtl_hw_initialize(struct rtl8169_private *tp)
--
1.7.10.4
[-- Attachment #2: 0001-r8169-csi_ops-signature-change.patch --]
[-- Type: text/plain, Size: 2992 bytes --]
>From 29b8c48d9b08fbc0e751460b2a46d3de426db2f5 Mon Sep 17 00:00:00 2001
Message-Id: <29b8c48d9b08fbc0e751460b2a46d3de426db2f5.1341578247.git.romieu@fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 6 Jul 2012 13:37:00 +0200
Subject: [PATCH 1/3] r8169: csi_ops signature change.
X-Organisation: Land of Sunshine Inc.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/realtek/r8169.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index c37aed9..adab11f 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -758,8 +758,8 @@ struct rtl8169_private {
} jumbo_ops;
struct csi_ops {
- void (*write)(void __iomem *, int, int);
- u32 (*read)(void __iomem *, int);
+ void (*write)(struct rtl8169_private *, int, int);
+ u32 (*read)(struct rtl8169_private *, int);
} csi_ops;
int (*set_speed)(struct net_device *, u8 aneg, u16 sp, u8 dpx, u32 adv);
@@ -4609,15 +4609,12 @@ static void rtl_hw_start_8169(struct net_device *dev)
static void rtl_csi_write(struct rtl8169_private *tp, int addr, int value)
{
if (tp->csi_ops.write)
- tp->csi_ops.write(tp->mmio_addr, addr, value);
+ tp->csi_ops.write(tp, addr, value);
}
static u32 rtl_csi_read(struct rtl8169_private *tp, int addr)
{
- if (tp->csi_ops.read)
- return tp->csi_ops.read(tp->mmio_addr, addr);
- else
- return ~0;
+ return tp->csi_ops.read ? tp->csi_ops.read(tp, addr) :~0;
}
static void rtl_csi_access_enable(struct rtl8169_private *tp, u32 bits)
@@ -4638,8 +4635,9 @@ static void rtl_csi_access_enable_2(struct rtl8169_private *tp)
rtl_csi_access_enable(tp, 0x27000000);
}
-static void r8169_csi_write(void __iomem *ioaddr, int addr, int value)
+static void r8169_csi_write(struct rtl8169_private *tp, int addr, int value)
{
+ void __iomem *ioaddr = tp->mmio_addr;
unsigned int i;
RTL_W32(CSIDR, value);
@@ -4653,8 +4651,9 @@ static void r8169_csi_write(void __iomem *ioaddr, int addr, int value)
}
}
-static u32 r8169_csi_read(void __iomem *ioaddr, int addr)
+static u32 r8169_csi_read(struct rtl8169_private *tp, int addr)
{
+ void __iomem *ioaddr = tp->mmio_addr;
u32 value = ~0x00;
unsigned int i;
@@ -4672,8 +4671,9 @@ static u32 r8169_csi_read(void __iomem *ioaddr, int addr)
return value;
}
-static void r8402_csi_write(void __iomem *ioaddr, int addr, int value)
+static void r8402_csi_write(struct rtl8169_private *tp, int addr, int value)
{
+ void __iomem *ioaddr = tp->mmio_addr;
unsigned int i;
RTL_W32(CSIDR, value);
@@ -4688,8 +4688,9 @@ static void r8402_csi_write(void __iomem *ioaddr, int addr, int value)
}
}
-static u32 r8402_csi_read(void __iomem *ioaddr, int addr)
+static u32 r8402_csi_read(struct rtl8169_private *tp, int addr)
{
+ void __iomem *ioaddr = tp->mmio_addr;
u32 value = ~0x00;
unsigned int i;
--
1.7.10.4
[-- Attachment #3: 0002-r8169-push-void-__iomem-deeper.patch --]
[-- Type: text/plain, Size: 24369 bytes --]
>From 4f9e2c24bbcbb2b0ae1c902597e4855ad25e4673 Mon Sep 17 00:00:00 2001
Message-Id: <4f9e2c24bbcbb2b0ae1c902597e4855ad25e4673.1341578247.git.romieu@fr.zoreil.com>
In-Reply-To: <29b8c48d9b08fbc0e751460b2a46d3de426db2f5.1341578247.git.romieu@fr.zoreil.com>
References: <29b8c48d9b08fbc0e751460b2a46d3de426db2f5.1341578247.git.romieu@fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Fri, 6 Jul 2012 13:56:55 +0200
Subject: [PATCH 2/3] r8169: push void __iomem * deeper.
X-Organisation: Land of Sunshine Inc.
I need more context than they carry and they are too easy to mess up
with anyway.
Concerned:
- r8168dp_1_mdio_access
- r8168dp_1_mdio_write
- rtl_ephy_write
- rtl_ephy_read
- rtl_eri_write
- rtl_eri_read
- rtl_w1w0_eri
- rtl_write_exgmac_batch
- rtl8168d_efuse_read
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/realtek/r8169.c | 245 ++++++++++++++++------------------
1 file changed, 116 insertions(+), 129 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index adab11f..0759c76 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -1104,12 +1104,12 @@ static int r8169_mdio_read(struct rtl8169_private *tp, int reg_addr)
return value;
}
-static void r8168dp_1_mdio_access(void __iomem *ioaddr, int reg_addr, u32 data)
+static void r8168dp_1_mdio_access(struct rtl8169_private *tp, int reg, u32 data)
{
+ void __iomem *ioaddr = tp->mmio_addr;
int i;
- RTL_W32(OCPDR, data |
- ((reg_addr & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT));
+ RTL_W32(OCPDR, data | ((reg & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT));
RTL_W32(OCPAR, OCPAR_GPHY_WRITE_CMD);
RTL_W32(EPHY_RXER_NUM, 0);
@@ -1120,13 +1120,10 @@ static void r8168dp_1_mdio_access(void __iomem *ioaddr, int reg_addr, u32 data)
}
}
-static
-void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg_addr, int value)
+static void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg, int value)
{
- void __iomem *ioaddr = tp->mmio_addr;
-
- r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_WRITE_CMD |
- (value & OCPDR_DATA_MASK));
+ r8168dp_1_mdio_access(tp, reg,
+ OCPDR_WRITE_CMD | (value & OCPDR_DATA_MASK));
}
static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg_addr)
@@ -1134,7 +1131,7 @@ static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg_addr)
void __iomem *ioaddr = tp->mmio_addr;
int i;
- r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_READ_CMD);
+ r8168dp_1_mdio_access(tp, reg_addr, OCPDR_READ_CMD);
mdelay(1);
RTL_W32(OCPAR, OCPAR_GPHY_READ_CMD);
@@ -1224,8 +1221,9 @@ static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
return rtl_readphy(tp, location);
}
-static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value)
+static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value)
{
+ void __iomem *ioaddr = tp->mmio_addr;
unsigned int i;
RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
@@ -1238,8 +1236,9 @@ static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value)
}
}
-static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr)
+static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr)
{
+ void __iomem *ioaddr = tp->mmio_addr;
u16 value = 0xffff;
unsigned int i;
@@ -1256,9 +1255,10 @@ static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr)
return value;
}
-static
-void rtl_eri_write(void __iomem *ioaddr, int addr, u32 mask, u32 val, int type)
+static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask,
+ u32 val, int type)
{
+ void __iomem *ioaddr = tp->mmio_addr;
unsigned int i;
BUG_ON((addr & 3) || (mask == 0));
@@ -1272,8 +1272,9 @@ void rtl_eri_write(void __iomem *ioaddr, int addr, u32 mask, u32 val, int type)
}
}
-static u32 rtl_eri_read(void __iomem *ioaddr, int addr, int type)
+static u32 rtl_eri_read(struct rtl8169_private *tp, int addr, int type)
{
+ void __iomem *ioaddr = tp->mmio_addr;
u32 value = ~0x00;
unsigned int i;
@@ -1290,13 +1291,13 @@ static u32 rtl_eri_read(void __iomem *ioaddr, int addr, int type)
return value;
}
-static void
-rtl_w1w0_eri(void __iomem *ioaddr, int addr, u32 mask, u32 p, u32 m, int type)
+static void rtl_w1w0_eri(struct rtl8169_private *tp, int addr, u32 mask, u32 p,
+ u32 m, int type)
{
u32 val;
- val = rtl_eri_read(ioaddr, addr, type);
- rtl_eri_write(ioaddr, addr, mask, (val & ~m) | p, type);
+ val = rtl_eri_read(tp, addr, type);
+ rtl_eri_write(tp, addr, mask, (val & ~m) | p, type);
}
struct exgmac_reg {
@@ -1305,17 +1306,18 @@ struct exgmac_reg {
u32 val;
};
-static void rtl_write_exgmac_batch(void __iomem *ioaddr,
+static void rtl_write_exgmac_batch(struct rtl8169_private *tp,
const struct exgmac_reg *r, int len)
{
while (len-- > 0) {
- rtl_eri_write(ioaddr, r->addr, r->mask, r->val, ERIAR_EXGMAC);
+ rtl_eri_write(tp, r->addr, r->mask, r->val, ERIAR_EXGMAC);
r++;
}
}
-static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr)
+static u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr)
{
+ void __iomem *ioaddr = tp->mmio_addr;
u8 value = 0xff;
unsigned int i;
@@ -1428,48 +1430,48 @@ static void rtl_link_chg_patch(struct rtl8169_private *tp)
if (tp->mac_version == RTL_GIGA_MAC_VER_34 ||
tp->mac_version == RTL_GIGA_MAC_VER_38) {
if (RTL_R8(PHYstatus) & _1000bpsF) {
- rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111,
- 0x00000011, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111,
- 0x00000005, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011,
+ ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005,
+ ERIAR_EXGMAC);
} else if (RTL_R8(PHYstatus) & _100bps) {
- rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111,
- 0x0000001f, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111,
- 0x00000005, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f,
+ ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005,
+ ERIAR_EXGMAC);
} else {
- rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111,
- 0x0000001f, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111,
- 0x0000003f, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f,
+ ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f,
+ ERIAR_EXGMAC);
}
/* Reset packet filter */
- rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01,
+ rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01,
ERIAR_EXGMAC);
- rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00,
+ rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00,
ERIAR_EXGMAC);
} else if (tp->mac_version == RTL_GIGA_MAC_VER_35 ||
tp->mac_version == RTL_GIGA_MAC_VER_36) {
if (RTL_R8(PHYstatus) & _1000bpsF) {
- rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111,
- 0x00000011, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111,
- 0x00000005, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011,
+ ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005,
+ ERIAR_EXGMAC);
} else {
- rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111,
- 0x0000001f, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111,
- 0x0000003f, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f,
+ ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f,
+ ERIAR_EXGMAC);
}
} else if (tp->mac_version == RTL_GIGA_MAC_VER_37) {
if (RTL_R8(PHYstatus) & _10bps) {
- rtl_eri_write(ioaddr, 0x1d0, ERIAR_MASK_0011,
- 0x4d02, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_0011,
- 0x0060, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x4d02,
+ ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1dc, ERIAR_MASK_0011, 0x0060,
+ ERIAR_EXGMAC);
} else {
- rtl_eri_write(ioaddr, 0x1d0, ERIAR_MASK_0011,
- 0x0000, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000,
+ ERIAR_EXGMAC);
}
}
}
@@ -2344,7 +2346,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
index -= regno;
break;
case PHY_READ_EFUSE:
- predata = rtl8168d_efuse_read(tp->mmio_addr, regno);
+ predata = rtl8168d_efuse_read(tp, regno);
index++;
break;
case PHY_CLEAR_READCOUNT:
@@ -2784,7 +2786,6 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
{ 0x1f, 0x0000 },
{ 0x0d, 0xf880 }
};
- void __iomem *ioaddr = tp->mmio_addr;
rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
@@ -2796,7 +2797,7 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
rtl_w1w0_phy(tp, 0x0b, 0x0010, 0x00ef);
rtl_w1w0_phy(tp, 0x0c, 0xa200, 0x5d00);
- if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
+ if (rtl8168d_efuse_read(tp, 0x01) == 0xb1) {
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0002 },
{ 0x05, 0x669a },
@@ -2896,11 +2897,10 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp)
{ 0x1f, 0x0000 },
{ 0x0d, 0xf880 }
};
- void __iomem *ioaddr = tp->mmio_addr;
rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
- if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
+ if (rtl8168d_efuse_read(tp, 0x01) == 0xb1) {
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0002 },
{ 0x05, 0x669a },
@@ -3168,8 +3168,7 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x1f, 0x0000);
/* EEE setting */
- rtl_w1w0_eri(tp->mmio_addr, 0x1b0, ERIAR_MASK_1111, 0x0000, 0x0003,
- ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_1111, 0x0000, 0x0003, ERIAR_EXGMAC);
rtl_writephy(tp, 0x1f, 0x0005);
rtl_writephy(tp, 0x05, 0x8b85);
rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000);
@@ -3273,7 +3272,6 @@ static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp)
static void rtl8411_hw_phy_config(struct rtl8169_private *tp)
{
- void __iomem *ioaddr = tp->mmio_addr;
static const struct phy_reg phy_reg_init[] = {
/* Channel estimation fine tune */
{ 0x1f, 0x0003 },
@@ -3347,7 +3345,7 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x1f, 0x0000);
/* eee setting */
- rtl_w1w0_eri(ioaddr, 0x1b0, ERIAR_MASK_0001, 0x00, 0x03, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_0001, 0x00, 0x03, ERIAR_EXGMAC);
rtl_writephy(tp, 0x1f, 0x0005);
rtl_writephy(tp, 0x05, 0x8b85);
rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000);
@@ -3463,8 +3461,6 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp)
static void rtl8402_hw_phy_config(struct rtl8169_private *tp)
{
- void __iomem *ioaddr = tp->mmio_addr;
-
/* Disable ALDPS before setting firmware */
rtl_writephy(tp, 0x1f, 0x0000);
rtl_writephy(tp, 0x18, 0x0310);
@@ -3473,7 +3469,7 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp)
rtl_apply_firmware(tp);
/* EEE setting */
- rtl_eri_write(ioaddr, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_writephy(tp, 0x1f, 0x0004);
rtl_writephy(tp, 0x10, 0x401f);
rtl_writephy(tp, 0x19, 0x7030);
@@ -3482,8 +3478,6 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp)
static void rtl8106e_hw_phy_config(struct rtl8169_private *tp)
{
- void __iomem *ioaddr = tp->mmio_addr;
-
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0004 },
{ 0x10, 0xc07f },
@@ -3498,10 +3492,10 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp)
rtl_apply_firmware(tp);
- rtl_eri_write(ioaddr, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
- rtl_eri_write(ioaddr, 0x1d0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
}
static void rtl_hw_phy_config(struct net_device *dev)
@@ -3754,7 +3748,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
low >> 16 },
};
- rtl_write_exgmac_batch(ioaddr, e, ARRAY_SIZE(e));
+ rtl_write_exgmac_batch(tp, e, ARRAY_SIZE(e));
}
RTL_W8(Cfg9346, Cfg9346_Lock);
@@ -4011,7 +4005,7 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
tp->mac_version == RTL_GIGA_MAC_VER_33)
- rtl_ephy_write(ioaddr, 0x19, 0xff64);
+ rtl_ephy_write(tp, 0x19, 0xff64);
if (rtl_wol_pll_power_down(tp))
return;
@@ -4750,13 +4744,14 @@ struct ephy_info {
u16 bits;
};
-static void rtl_ephy_init(void __iomem *ioaddr, const struct ephy_info *e, int len)
+static void rtl_ephy_init(struct rtl8169_private *tp, const struct ephy_info *e,
+ int len)
{
u16 w;
while (len-- > 0) {
- w = (rtl_ephy_read(ioaddr, e->offset) & ~e->mask) | e->bits;
- rtl_ephy_write(ioaddr, e->offset, w);
+ w = (rtl_ephy_read(tp, e->offset) & ~e->mask) | e->bits;
+ rtl_ephy_write(tp, e->offset, w);
e++;
}
}
@@ -4840,7 +4835,6 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp)
static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp)
{
- void __iomem *ioaddr = tp->mmio_addr;
static const struct ephy_info e_info_8168cp[] = {
{ 0x01, 0, 0x0001 },
{ 0x02, 0x0800, 0x1000 },
@@ -4851,7 +4845,7 @@ static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp)
rtl_csi_access_enable_2(tp);
- rtl_ephy_init(ioaddr, e_info_8168cp, ARRAY_SIZE(e_info_8168cp));
+ rtl_ephy_init(tp, e_info_8168cp, ARRAY_SIZE(e_info_8168cp));
__rtl_hw_start_8168cp(tp);
}
@@ -4902,14 +4896,13 @@ static void rtl_hw_start_8168c_1(struct rtl8169_private *tp)
RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2);
- rtl_ephy_init(ioaddr, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1));
+ rtl_ephy_init(tp, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1));
__rtl_hw_start_8168cp(tp);
}
static void rtl_hw_start_8168c_2(struct rtl8169_private *tp)
{
- void __iomem *ioaddr = tp->mmio_addr;
static const struct ephy_info e_info_8168c_2[] = {
{ 0x01, 0, 0x0001 },
{ 0x03, 0x0400, 0x0220 }
@@ -4917,7 +4910,7 @@ static void rtl_hw_start_8168c_2(struct rtl8169_private *tp)
rtl_csi_access_enable_2(tp);
- rtl_ephy_init(ioaddr, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2));
+ rtl_ephy_init(tp, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2));
__rtl_hw_start_8168cp(tp);
}
@@ -4985,8 +4978,8 @@ static void rtl_hw_start_8168d_4(struct rtl8169_private *tp)
const struct ephy_info *e = e_info_8168d_4 + i;
u16 w;
- w = rtl_ephy_read(ioaddr, e->offset);
- rtl_ephy_write(ioaddr, 0x03, (w & e->mask) | e->bits);
+ w = rtl_ephy_read(tp, e->offset);
+ rtl_ephy_write(tp, 0x03, (w & e->mask) | e->bits);
}
rtl_enable_clock_request(pdev);
@@ -5014,7 +5007,7 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp)
rtl_csi_access_enable_2(tp);
- rtl_ephy_init(ioaddr, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1));
+ rtl_ephy_init(tp, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1));
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
@@ -5040,18 +5033,18 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
rtl_csi_access_enable_1(tp);
- rtl_ephy_init(ioaddr, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2));
+ rtl_ephy_init(tp, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2));
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
- rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_1111, 0x07ff0060, ERIAR_EXGMAC);
- rtl_w1w0_eri(ioaddr, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC);
- rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00,
+ rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x07ff0060, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00,
ERIAR_EXGMAC);
RTL_W8(MaxTxPacketSize, EarlySize);
@@ -5078,16 +5071,16 @@ static void rtl_hw_start_8168f(struct rtl8169_private *tp)
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
- rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
- rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
- rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
- rtl_w1w0_eri(ioaddr, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC);
- rtl_w1w0_eri(ioaddr, 0x1d0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_1111, 0x00000060, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0x1d0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x00000060, ERIAR_EXGMAC);
RTL_W8(MaxTxPacketSize, EarlySize);
@@ -5112,10 +5105,9 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
rtl_hw_start_8168f(tp);
- rtl_ephy_init(ioaddr, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1));
+ rtl_ephy_init(tp, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1));
- rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00,
- ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, ERIAR_EXGMAC);
/* Adjust EEE LED frequency */
RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07);
@@ -5123,7 +5115,6 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
static void rtl_hw_start_8411(struct rtl8169_private *tp)
{
- void __iomem *ioaddr = tp->mmio_addr;
static const struct ephy_info e_info_8168f_1[] = {
{ 0x06, 0x00c0, 0x0020 },
{ 0x0f, 0xffff, 0x5200 },
@@ -5133,10 +5124,9 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp)
rtl_hw_start_8168f(tp);
- rtl_ephy_init(ioaddr, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1));
+ rtl_ephy_init(tp, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1));
- rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0x0000,
- ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0x0000, ERIAR_EXGMAC);
}
static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
@@ -5144,29 +5134,29 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
void __iomem *ioaddr = tp->mmio_addr;
struct pci_dev *pdev = tp->pci_dev;
- rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_0101, 0x080002, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_0001, 0x48, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xc8, ERIAR_MASK_0101, 0x080002, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xd0, ERIAR_MASK_0001, 0x48, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
rtl_csi_access_enable_1(tp);
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
- rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
- rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN);
RTL_W8(MaxTxPacketSize, EarlySize);
- rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
/* Adjust EEE LED frequency */
RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07);
- rtl_w1w0_eri(ioaddr, 0x2fc, ERIAR_MASK_0001, 0x01, 0x02, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x02, ERIAR_EXGMAC);
}
static void rtl_hw_start_8168(struct net_device *dev)
@@ -5329,7 +5319,7 @@ static void rtl_hw_start_8102e_1(struct rtl8169_private *tp)
if ((cfg1 & LEDS0) && (cfg1 & LEDS1))
RTL_W8(Config1, cfg1 & ~LEDS0);
- rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1));
+ rtl_ephy_init(tp, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1));
}
static void rtl_hw_start_8102e_2(struct rtl8169_private *tp)
@@ -5349,7 +5339,7 @@ static void rtl_hw_start_8102e_3(struct rtl8169_private *tp)
{
rtl_hw_start_8102e_2(tp);
- rtl_ephy_write(tp->mmio_addr, 0x03, 0xc2f9);
+ rtl_ephy_write(tp, 0x03, 0xc2f9);
}
static void rtl_hw_start_8105e_1(struct rtl8169_private *tp)
@@ -5375,15 +5365,13 @@ static void rtl_hw_start_8105e_1(struct rtl8169_private *tp)
RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);
RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN);
- rtl_ephy_init(ioaddr, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1));
+ rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1));
}
static void rtl_hw_start_8105e_2(struct rtl8169_private *tp)
{
- void __iomem *ioaddr = tp->mmio_addr;
-
rtl_hw_start_8105e_1(tp);
- rtl_ephy_write(ioaddr, 0x1e, rtl_ephy_read(ioaddr, 0x1e) | 0x8000);
+ rtl_ephy_write(tp, 0x1e, rtl_ephy_read(tp, 0x1e) | 0x8000);
}
static void rtl_hw_start_8402(struct rtl8169_private *tp)
@@ -5402,18 +5390,17 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)
RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO);
RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB);
- rtl_ephy_init(ioaddr, e_info_8402, ARRAY_SIZE(e_info_8402));
+ rtl_ephy_init(tp, e_info_8402, ARRAY_SIZE(e_info_8402));
rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT);
- rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_1111, 0x00000002, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00000006, ERIAR_EXGMAC);
- rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
- rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
- rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
- rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0e00, 0xff00,
- ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, 0x00000002, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00000006, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+ rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+ rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0e00, 0xff00, ERIAR_EXGMAC);
}
static void rtl_hw_start_8106(struct rtl8169_private *tp)
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH 1/4] asix: Fix checkpatch warnings
From: Joe Perches @ 2012-07-06 15:25 UTC (permalink / raw)
To: Christian Riesch
Cc: netdev, Oliver Neukum, Eric Dumazet, Allan Chou, Mark Lord,
Grant Grundler, Ming Lei, Michael Riesch
In-Reply-To: <1341574388-7464-2-git-send-email-christian.riesch@omicron.at>
On Fri, 2012-07-06 at 13:33 +0200, Christian Riesch wrote:
>
Hi Christian. Just some trivial comments for a
trivial cleanup patch.
> diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
> index 3ae80ec..9210f40 100644
> --- a/drivers/net/usb/asix.c
> +++ b/drivers/net/usb/asix.c
> @@ -20,8 +20,8 @@
> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> */
>
> -// #define DEBUG // error path messages, extra info
> -// #define VERBOSE // more; success messages
> +/* #define DEBUG */ /* error path messages, extra info */
> +/* #define VERBOSE */ /* more; success messages */
Might as well delete as change the comment style.
It isn't applicable after the patch.
> @@ -253,8 +253,8 @@ static void asix_async_cmd_callback(struct urb *urb)
> int status = urb->status;
>
> if (status < 0)
> - printk(KERN_DEBUG "asix_async_cmd_callback() failed with %d",
> - status);
> + pr_debug("asix_async_cmd_callback() failed with %d",
> + status);
Probably better with "%s: "..., __func__, ...
Missing a newline too.
There are several other uses of embedded function names
that could be modified.
> @@ -432,7 +433,8 @@ static inline int asix_get_phy_addr(struct usbnet *dev)
> netdev_dbg(dev->net, "asix_get_phy_addr()\n");
>
> if (ret < 0) {
> - netdev_err(dev->net, "Error reading PHYID register: %02x\n", ret);
> + netdev_err(dev->net, "Error reading PHYID register: %02x\n",
> + ret);
80 column zealotry? If you want, but it's probably past
the time that's really desirable or necessary.
> @@ -575,7 +580,7 @@ static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc)
> mutex_lock(&dev->phy_mutex);
> asix_set_sw_mii(dev);
> asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id,
> - (__u16)loc, 2, &res);
> + (__u16)loc, 2, &res);
Fits on 1 line.
> +static void asix_get_drvinfo(struct net_device *net,
> + struct ethtool_drvinfo *info)
> {
> struct usbnet *dev = netdev_priv(net);
> struct asix_data *data = (struct asix_data *)&dev->data;
>
> /* Inherit standard device info */
> usbnet_get_drvinfo(net, info);
> - strncpy (info->driver, DRIVER_NAME, sizeof info->driver);
> - strncpy (info->version, DRIVER_VERSION, sizeof info->version);
> + strncpy(info->driver, DRIVER_NAME, sizeof info->driver);
> + strncpy(info->version, DRIVER_VERSION, sizeof info->version);
Most every kernel use of sizeof uses parens like:
strncpy(info->driver, DRIVER_NAME, sizeof(info->driver));
strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
@@ -1510,133 +1520,133 @@ static const struct driver_info ax88178_info = {
> .tx_fixup = asix_tx_fixup,
> };
>
> -static const struct usb_device_id products [] = {
> +static const struct usb_device_id products[] = {
Maybe use a space not a tab after usb_device_id.
> {
> - // Linksys USB200M
> - USB_DEVICE (0x077b, 0x2226),
> + /* Linksys USB200M */
> + USB_DEVICE(0x077b, 0x2226),
> .driver_info = (unsigned long) &ax8817x_info,
> }, {
I think all of these would look more reasonable on single
lines like
{ USB_DEVICE(0xxxxx, 0xxxxx), .driver_info = (unsigned long)&func },
or maybe add another macro like:
#define ASIX_USB_DEVICE(vendor, product, driver) \
USB_DEVICE(vendor, product), .driver_info = (unsigned long)driver)
and make these
{ ASIX_USB_DEVICE(0xxxxx, 0xxxxx, &func) }, /* description */
Come to think of it, the & for the function address
isn't necessary either.
cheers, Joe
^ permalink raw reply
* Re: [PATCH v2 net-next 2/2] r8169: support RTL8168G
From: Francois Romieu @ 2012-07-06 15:20 UTC (permalink / raw)
To: hayeswang; +Cc: netdev, linux-kernel
In-Reply-To: <43E32504589B47B9846C4E9DAF98BF60@realtek.com.tw>
hayeswang <hayeswang@realtek.com> :
> Francois Romieu [romieu@fr.zoreil.com]
[...]
> > - fix r8168g_mdio_write (if (reg_addr == 0x1f) { if (reg_addr == 0) snafu)
> > -> Please check this one.
>
> That is fine.
Thanks, I'll merge your patch and feed both drivers to davem.
--
Ueimor
^ permalink raw reply
* Re: [RFC PATCH] bridge: netfilter: fix skb->nf_bridge NULL panic in br_nf_forward_finish
From: Eric Dumazet @ 2012-07-06 15:06 UTC (permalink / raw)
To: Lin Ming
Cc: Massimo Cetra, netdev, Stephen Hemminger, David S. Miller,
Julian Anastasov
In-Reply-To: <1341584394.4789.34.camel@chief-river-32>
On Fri, 2012-07-06 at 22:19 +0800, Lin Ming wrote:
> I can reproduce similiar panic with 3.5-rc5 kernel as Massimo reported at:
> http://marc.info/?l=linux-netdev&m=134089242113979&w=2
>
> The steps to reproduce as follow,
>
> 1. On Host1, setup brige br0(192.168.1.106)
> 2. Boot a kvm guest(192.168.1.105) on Host1 and start httpd
> 3. Start IPVS service on Host1
> ipvsadm -A -t 192.168.1.106:80 -s rr
> ipvsadm -a -t 192.168.1.106:80 -r 192.168.1.105:80 -m
> 4. Run apache benchmark on Host2(192.168.1.101)
> ab -n 1000 http://192.168.1.106/
>
> The panic happened in br_nf_forward_finish because skb->nf_bridge is NULL.
> skb->nf_bridge is set to NULL in ip_vs_reply4 hook.
>
> br_nf_forward_ip():
> NF_HOOK(pf, NF_INET_FORWARD, skb, brnf_get_logical_dev(skb, in), parent,
> br_nf_forward_finish);
>
> This calls IPVS hook ip_vs_reply4.
>
> ip_vs_reply4
> ip_vs_out
> handle_response
> ip_vs_notrack
> nf_reset()
> {
> skb->nf_bridge = NULL;
> }
>
> This patch added skb->nf_bridge check in br_nf_forward_finish and the panic gone.
> But I am really not sure if this is the right fix.
> Please help to review.
>
> The panic log attached.
...
> Signed-off-by: Lin Ming <mlin@ss.pku.edu.cn>
> ---
> net/bridge/br_netfilter.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
> index e41456b..10da415 100644
> --- a/net/bridge/br_netfilter.c
> +++ b/net/bridge/br_netfilter.c
> @@ -719,7 +719,7 @@ static int br_nf_forward_finish(struct sk_buff *skb)
> struct nf_bridge_info *nf_bridge = skb->nf_bridge;
> struct net_device *in;
>
> - if (!IS_ARP(skb) && !IS_VLAN_ARP(skb)) {
> + if (!IS_ARP(skb) && !IS_VLAN_ARP(skb) && nf_bridge) {
> in = nf_bridge->physindev;
> if (nf_bridge->mask & BRNF_PKT_TYPE) {
> skb->pkt_type = PACKET_OTHERHOST;
So after your patch we have the code in the else clause :
} else {
in = *((struct net_device **)(skb->cb));
}
But do we really have a "struct net_device" pointer stored in skb->cb[]
at this stage ?
AFAIK this is set only for ARP_FORWARD (br_nf_forward_arp() line 838 :
*d = (struct net_device *)in;),
not in br_nf_forward_ip()
If we have garbage instead, we can have other bugs later...
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox