745-v5.7-net-dsa-mt7530-add-support-for-port-mirroring.patch 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. From 37feab6076aa816ed72fe836759a485353241916 Mon Sep 17 00:00:00 2001
  2. From: DENG Qingfang <[email protected]>
  3. Date: Fri, 6 Mar 2020 20:35:35 +0800
  4. Subject: net: dsa: mt7530: add support for port mirroring
  5. Add support for configuring port mirroring through the cls_matchall
  6. classifier. We do a full ingress and/or egress capture towards a
  7. capture port.
  8. MT7530 supports one monitor port and multiple mirrored ports.
  9. Signed-off-by: DENG Qingfang <[email protected]>
  10. Signed-off-by: David S. Miller <[email protected]>
  11. ---
  12. drivers/net/dsa/mt7530.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
  13. drivers/net/dsa/mt7530.h | 7 ++++++
  14. 2 files changed, 67 insertions(+)
  15. --- a/drivers/net/dsa/mt7530.c
  16. +++ b/drivers/net/dsa/mt7530.c
  17. @@ -1151,6 +1151,64 @@ mt7530_port_vlan_del(struct dsa_switch *
  18. return 0;
  19. }
  20. +static int mt7530_port_mirror_add(struct dsa_switch *ds, int port,
  21. + struct dsa_mall_mirror_tc_entry *mirror,
  22. + bool ingress)
  23. +{
  24. + struct mt7530_priv *priv = ds->priv;
  25. + u32 val;
  26. +
  27. + /* Check for existent entry */
  28. + if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
  29. + return -EEXIST;
  30. +
  31. + val = mt7530_read(priv, MT7530_MFC);
  32. +
  33. + /* MT7530 only supports one monitor port */
  34. + if (val & MIRROR_EN && MIRROR_PORT(val) != mirror->to_local_port)
  35. + return -EEXIST;
  36. +
  37. + val |= MIRROR_EN;
  38. + val &= ~MIRROR_MASK;
  39. + val |= mirror->to_local_port;
  40. + mt7530_write(priv, MT7530_MFC, val);
  41. +
  42. + val = mt7530_read(priv, MT7530_PCR_P(port));
  43. + if (ingress) {
  44. + val |= PORT_RX_MIR;
  45. + priv->mirror_rx |= BIT(port);
  46. + } else {
  47. + val |= PORT_TX_MIR;
  48. + priv->mirror_tx |= BIT(port);
  49. + }
  50. + mt7530_write(priv, MT7530_PCR_P(port), val);
  51. +
  52. + return 0;
  53. +}
  54. +
  55. +static void mt7530_port_mirror_del(struct dsa_switch *ds, int port,
  56. + struct dsa_mall_mirror_tc_entry *mirror)
  57. +{
  58. + struct mt7530_priv *priv = ds->priv;
  59. + u32 val;
  60. +
  61. + val = mt7530_read(priv, MT7530_PCR_P(port));
  62. + if (mirror->ingress) {
  63. + val &= ~PORT_RX_MIR;
  64. + priv->mirror_rx &= ~BIT(port);
  65. + } else {
  66. + val &= ~PORT_TX_MIR;
  67. + priv->mirror_tx &= ~BIT(port);
  68. + }
  69. + mt7530_write(priv, MT7530_PCR_P(port), val);
  70. +
  71. + if (!priv->mirror_rx && !priv->mirror_tx) {
  72. + val = mt7530_read(priv, MT7530_MFC);
  73. + val &= ~MIRROR_EN;
  74. + mt7530_write(priv, MT7530_MFC, val);
  75. + }
  76. +}
  77. +
  78. static enum dsa_tag_protocol
  79. mtk_get_tag_protocol(struct dsa_switch *ds, int port)
  80. {
  81. @@ -1530,6 +1588,8 @@ static const struct dsa_switch_ops mt753
  82. .port_vlan_prepare = mt7530_port_vlan_prepare,
  83. .port_vlan_add = mt7530_port_vlan_add,
  84. .port_vlan_del = mt7530_port_vlan_del,
  85. + .port_mirror_add = mt7530_port_mirror_add,
  86. + .port_mirror_del = mt7530_port_mirror_del,
  87. .phylink_validate = mt7530_phylink_validate,
  88. .phylink_mac_link_state = mt7530_phylink_mac_link_state,
  89. .phylink_mac_config = mt7530_phylink_mac_config,
  90. --- a/drivers/net/dsa/mt7530.h
  91. +++ b/drivers/net/dsa/mt7530.h
  92. @@ -36,6 +36,9 @@ enum {
  93. #define CPU_EN BIT(7)
  94. #define CPU_PORT(x) ((x) << 4)
  95. #define CPU_MASK (0xf << 4)
  96. +#define MIRROR_EN BIT(3)
  97. +#define MIRROR_PORT(x) ((x) & 0x7)
  98. +#define MIRROR_MASK 0x7
  99. /* Registers for address table access */
  100. #define MT7530_ATA1 0x74
  101. @@ -141,6 +144,8 @@ enum mt7530_stp_state {
  102. /* Register for port control */
  103. #define MT7530_PCR_P(x) (0x2004 + ((x) * 0x100))
  104. +#define PORT_TX_MIR BIT(9)
  105. +#define PORT_RX_MIR BIT(8)
  106. #define PORT_VLAN(x) ((x) & 0x3)
  107. enum mt7530_port_mode {
  108. @@ -457,6 +462,8 @@ struct mt7530_priv {
  109. phy_interface_t p6_interface;
  110. phy_interface_t p5_interface;
  111. unsigned int p5_intf_sel;
  112. + u8 mirror_rx;
  113. + u8 mirror_tx;
  114. struct mt7530_port ports[MT7530_NUM_PORTS];
  115. /* protect among processes for registers access*/