summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/freescale/fec.h
diff options
context:
space:
mode:
authorFrank Li <Frank.Li@freescale.com>2013-05-07 16:08:44 +0200
committerDavid S. Miller <davem@davemloft.net>2013-05-08 22:13:30 +0200
commit54309fa60b5f57b90c1842176f6045e665d21142 (patch)
tree31bb2d5574adc10d342a01b2081c9907e917c554 /drivers/net/ethernet/freescale/fec.h
parentbfin_mac: fix error return code in bfin_mac_probe() (diff)
downloadlinux-54309fa60b5f57b90c1842176f6045e665d21142.tar.xz
linux-54309fa60b5f57b90c1842176f6045e665d21142.zip
net: fec: fix kernel oops when plug/unplug cable many times
reproduce steps 1. flood ping from other machine ping -f -s 41000 IP 2. run below script while [ 1 ]; do ethtool -s eth0 autoneg off; sleep 3;ethtool -s eth0 autoneg on; sleep 4; done; You can see oops in one hour. The reason is fec_restart clear BD but NAPI may use it. The solution is disable NAPI and stop xmit when reset BD. disable NAPI may sleep, so fec_restart can't be call in atomic context. Signed-off-by: Frank Li <Frank.Li@freescale.com> Reviewed-by: Lucas Stach <l.stach@pengutronix.de> Tested-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/freescale/fec.h')
-rw-r--r--drivers/net/ethernet/freescale/fec.h10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index ceb4d43c132d..9ce5b7185fda 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -198,6 +198,11 @@ struct bufdesc_ex {
#define FLAG_RX_CSUM_ENABLED (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
#define FLAG_RX_CSUM_ERROR (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
+struct fec_enet_delayed_work {
+ struct delayed_work delay_work;
+ bool timeout;
+};
+
/* The FEC buffer descriptors track the ring buffers. The rx_bd_base and
* tx_bd_base always point to the base of the buffer descriptors. The
* cur_rx and cur_tx point to the currently available buffer.
@@ -232,9 +237,6 @@ struct fec_enet_private {
/* The ring entries to be free()ed */
struct bufdesc *dirty_tx;
- /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
- spinlock_t hw_lock;
-
struct platform_device *pdev;
int opened;
@@ -269,7 +271,7 @@ struct fec_enet_private {
int hwts_rx_en;
int hwts_tx_en;
struct timer_list time_keep;
-
+ struct fec_enet_delayed_work delay_work;
};
void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev);