0066-net-mediatek-fix-mtk_pending_work.patch 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. From e2cc73e6ddb0cc39b8f58654a449651a621916a9 Mon Sep 17 00:00:00 2001
  2. From: John Crispin <blogic@openwrt.org>
  3. Date: Tue, 29 Mar 2016 17:00:47 +0200
  4. Subject: [PATCH 066/102] net: mediatek: fix mtk_pending_work
  5. The driver supports 2 MACs. Both run on the same DMA ring. If we hit a TX
  6. timeout we need to stop both netdevs before retarting them again. If we
  7. dont do thsi, mtk_stop() wont shutdown DMA and the consecutive call to
  8. mtk_open() wont restart DMA and enable IRQs.
  9. Signed-off-by: John Crispin <blogic@openwrt.org>
  10. ---
  11. drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++--------
  12. 1 file changed, 21 insertions(+), 9 deletions(-)
  13. --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
  14. +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
  15. @@ -1430,19 +1430,31 @@ static int mtk_do_ioctl(struct net_devic
  16. static void mtk_pending_work(struct work_struct *work)
  17. {
  18. - struct mtk_mac *mac = container_of(work, struct mtk_mac, pending_work);
  19. - struct mtk_eth *eth = mac->hw;
  20. - struct net_device *dev = eth->netdev[mac->id];
  21. - int err;
  22. + struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work);
  23. + int err, i;
  24. + unsigned long restart = 0;
  25. rtnl_lock();
  26. - mtk_stop(dev);
  27. - err = mtk_open(dev);
  28. - if (err) {
  29. - netif_alert(eth, ifup, dev,
  30. + /* stop all devices to make sure that dma is properly shut down */
  31. + for (i = 0; i < MTK_MAC_COUNT; i++) {
  32. + if (!netif_oper_up(eth->netdev[i]))
  33. + continue;
  34. + mtk_stop(eth->netdev[i]);
  35. + __set_bit(i, &restart);
  36. + }
  37. +
  38. +
  39. + /* restart DMA and enable IRQs */
  40. + for (i = 0; i < MTK_MAC_COUNT; i++) {
  41. + if (!test_bit(i, &restart))
  42. + continue;
  43. + err = mtk_open(eth->netdev[i]);
  44. + if (err) {
  45. + netif_alert(eth, ifup, eth->netdev[i],
  46. "Driver up/down cycle failed, closing device.\n");
  47. - dev_close(dev);
  48. + dev_close(eth->netdev[i]);
  49. + }
  50. }
  51. rtnl_unlock();
  52. }