igc_base.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2018 Intel Corporation */
  3. #include <linux/delay.h>
  4. #include "igc_hw.h"
  5. #include "igc_i225.h"
  6. /**
  7. * igc_rx_fifo_flush_base - Clean rx fifo after Rx enable
  8. * @hw: pointer to the HW structure
  9. *
  10. * After Rx enable, if manageability is enabled then there is likely some
  11. * bad data at the start of the fifo and possibly in the DMA fifo. This
  12. * function clears the fifos and flushes any packets that came in as rx was
  13. * being enabled.
  14. */
  15. void igc_rx_fifo_flush_base(struct igc_hw *hw)
  16. {
  17. u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
  18. int i, ms_wait;
  19. /* disable IPv6 options as per hardware errata */
  20. rfctl = rd32(IGC_RFCTL);
  21. rfctl |= IGC_RFCTL_IPV6_EX_DIS;
  22. wr32(IGC_RFCTL, rfctl);
  23. if (!(rd32(IGC_MANC) & IGC_MANC_RCV_TCO_EN))
  24. return;
  25. /* Disable all Rx queues */
  26. for (i = 0; i < 4; i++) {
  27. rxdctl[i] = rd32(IGC_RXDCTL(i));
  28. wr32(IGC_RXDCTL(i),
  29. rxdctl[i] & ~IGC_RXDCTL_QUEUE_ENABLE);
  30. }
  31. /* Poll all queues to verify they have shut down */
  32. for (ms_wait = 0; ms_wait < 10; ms_wait++) {
  33. usleep_range(1000, 2000);
  34. rx_enabled = 0;
  35. for (i = 0; i < 4; i++)
  36. rx_enabled |= rd32(IGC_RXDCTL(i));
  37. if (!(rx_enabled & IGC_RXDCTL_QUEUE_ENABLE))
  38. break;
  39. }
  40. if (ms_wait == 10)
  41. pr_debug("Queue disable timed out after 10ms\n");
  42. /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
  43. * incoming packets are rejected. Set enable and wait 2ms so that
  44. * any packet that was coming in as RCTL.EN was set is flushed
  45. */
  46. wr32(IGC_RFCTL, rfctl & ~IGC_RFCTL_LEF);
  47. rlpml = rd32(IGC_RLPML);
  48. wr32(IGC_RLPML, 0);
  49. rctl = rd32(IGC_RCTL);
  50. temp_rctl = rctl & ~(IGC_RCTL_EN | IGC_RCTL_SBP);
  51. temp_rctl |= IGC_RCTL_LPE;
  52. wr32(IGC_RCTL, temp_rctl);
  53. wr32(IGC_RCTL, temp_rctl | IGC_RCTL_EN);
  54. wrfl();
  55. usleep_range(2000, 3000);
  56. /* Enable Rx queues that were previously enabled and restore our
  57. * previous state
  58. */
  59. for (i = 0; i < 4; i++)
  60. wr32(IGC_RXDCTL(i), rxdctl[i]);
  61. wr32(IGC_RCTL, rctl);
  62. wrfl();
  63. wr32(IGC_RLPML, rlpml);
  64. wr32(IGC_RFCTL, rfctl);
  65. /* Flush receive errors generated by workaround */
  66. rd32(IGC_ROC);
  67. rd32(IGC_RNBC);
  68. rd32(IGC_MPC);
  69. }