12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- From e2cc73e6ddb0cc39b8f58654a449651a621916a9 Mon Sep 17 00:00:00 2001
- From: John Crispin <blogic@openwrt.org>
- Date: Tue, 29 Mar 2016 17:00:47 +0200
- Subject: [PATCH 066/102] net: mediatek: fix mtk_pending_work
- The driver supports 2 MACs. Both run on the same DMA ring. If we hit a TX
- timeout we need to stop both netdevs before retarting them again. If we
- dont do thsi, mtk_stop() wont shutdown DMA and the consecutive call to
- mtk_open() wont restart DMA and enable IRQs.
- Signed-off-by: John Crispin <blogic@openwrt.org>
- ---
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++--------
- 1 file changed, 21 insertions(+), 9 deletions(-)
- --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
- +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
- @@ -1430,19 +1430,31 @@ static int mtk_do_ioctl(struct net_devic
-
- static void mtk_pending_work(struct work_struct *work)
- {
- - struct mtk_mac *mac = container_of(work, struct mtk_mac, pending_work);
- - struct mtk_eth *eth = mac->hw;
- - struct net_device *dev = eth->netdev[mac->id];
- - int err;
- + struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work);
- + int err, i;
- + unsigned long restart = 0;
-
- rtnl_lock();
- - mtk_stop(dev);
-
- - err = mtk_open(dev);
- - if (err) {
- - netif_alert(eth, ifup, dev,
- + /* stop all devices to make sure that dma is properly shut down */
- + for (i = 0; i < MTK_MAC_COUNT; i++) {
- + if (!netif_oper_up(eth->netdev[i]))
- + continue;
- + mtk_stop(eth->netdev[i]);
- + __set_bit(i, &restart);
- + }
- +
- +
- + /* restart DMA and enable IRQs */
- + for (i = 0; i < MTK_MAC_COUNT; i++) {
- + if (!test_bit(i, &restart))
- + continue;
- + err = mtk_open(eth->netdev[i]);
- + if (err) {
- + netif_alert(eth, ifup, eth->netdev[i],
- "Driver up/down cycle failed, closing device.\n");
- - dev_close(dev);
- + dev_close(eth->netdev[i]);
- + }
- }
- rtnl_unlock();
- }
|