<div dir="ltr"><div>This exposes hardware port mirroring in ag71xx driver (e.g. TL-WR841ND) via swconfig API. It's my first patch ever so any feedback is welcome. </div><div><br></div><div>Signed-off-by: Milan Krstic <<a href="mailto:milan.krstic@gmail.com">milan.krstic@gmail.com</a>></div><div>---</div><div> .../net/ethernet/atheros/ag71xx/ag71xx_ar7240.c    | 154 +++++++++++++++++++++</div><div> 1 file changed, 154 insertions(+)</div><div><br></div><div>diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c</div><div>index c5aed0d..da9c0dd 100644</div><div>--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c</div><div>+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c</div><div>@@ -77,6 +77,7 @@</div><div> </div><div> #define AR7240_REG_CPU_PORT<span class="gmail-Apple-tab-span" style="white-space:pre">             </span>0x78</div><div> #define AR7240_MIRROR_PORT_S<span class="gmail-Apple-tab-span" style="white-space:pre">             </span>4</div><div>+#define AR7240_MIRROR_PORT_M<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>BITM(4)</div><div> #define AR7240_CPU_PORT_EN<span class="gmail-Apple-tab-span" style="white-space:pre">            </span>BIT(8)</div><div> </div><div> #define AR7240_REG_MIB_FUNCTION0<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>0x80</div><div>@@ -1013,6 +1014,134 @@ ar7240_get_port_stats(struct switch_dev *dev, int port,</div><div> <span class="gmail-Apple-tab-span" style="white-space:pre">   </span>return 0;</div><div> }</div><div> </div><div>+static int</div><div>+ar7240_set_mirror_monitor_port(struct switch_dev *dev,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">                  </span>       const struct switch_attr *attr,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>       struct switch_val *val)</div><div>+{</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>struct ar7240sw *as = sw_to_ar7240(dev);</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>struct mii_bus *mii = as->mii_bus;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>int port = val->value.i;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>if (port > 15)</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">             </span>return -EINVAL;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>ar7240sw_reg_rmw(mii, AR7240_REG_CPU_PORT,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>AR7240_MIRROR_PORT_M << AR7240_MIRROR_PORT_S,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">                   </span>port << AR7240_MIRROR_PORT_S);</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>return 0;</div><div>+}</div><div>+</div><div>+static int</div><div>+ar7240_get_mirror_monitor_port(struct switch_dev *dev,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>       const struct switch_attr *attr,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>       struct switch_val *val)</div><div>+{</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>struct ar7240sw *as = sw_to_ar7240(dev);</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>struct mii_bus *mii = as->mii_bus;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>u32 ret;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>ret = ar7240sw_reg_read(mii, AR7240_REG_CPU_PORT);</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>val->value.i = (ret >> AR7240_MIRROR_PORT_S) & AR7240_MIRROR_PORT_M;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>return 0;</div><div>+}</div><div>+</div><div>+static int</div><div>+ar7240_set_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>     struct switch_val *val)</div><div>+{</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>struct ar7240sw *as = sw_to_ar7240(dev);</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>struct mii_bus *mii = as->mii_bus;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>int port = val->port_vlan;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>if (port >= dev->ports)</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>return -EINVAL;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>if (val && val->value.i == 1)</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>ar7240sw_reg_set(mii, AR7240_REG_PORT_CTRL(port),</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>AR7240_PORT_CTRL_MIRROR_RX);</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>else</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">          </span>ar7240sw_reg_rmw(mii, AR7240_REG_PORT_CTRL(port),</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>AR7240_PORT_CTRL_MIRROR_RX, 0);</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>return 0;</div><div>+}</div><div>+</div><div>+static int</div><div>+ar7240_get_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>     struct switch_val *val)</div><div>+{</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>struct ar7240sw *as = sw_to_ar7240(dev);</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>struct mii_bus *mii = as->mii_bus;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>u32 ctrl;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>int port = val->port_vlan;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>if (port >= dev->ports)</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>return -EINVAL;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>ctrl = ar7240sw_reg_read(mii, AR7240_REG_PORT_CTRL(port));</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>if ((ctrl & AR7240_PORT_CTRL_MIRROR_RX) == AR7240_PORT_CTRL_MIRROR_RX)</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">            </span>val->value.i = 1;</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>else</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">          </span>val->value.i = 0;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>return 0;</div><div>+}</div><div>+</div><div>+static int</div><div>+ar7240_set_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>     struct switch_val *val)</div><div>+{</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>struct ar7240sw *as = sw_to_ar7240(dev);</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>struct mii_bus *mii = as->mii_bus;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>int port = val->port_vlan;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>if (port >= dev->ports)</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>return -EINVAL;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>if (val && val->value.i == 1)</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>ar7240sw_reg_set(mii, AR7240_REG_PORT_CTRL(port),</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>AR7240_PORT_CTRL_MIRROR_TX);</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>else</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">          </span>ar7240sw_reg_rmw(mii, AR7240_REG_PORT_CTRL(port),</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>AR7240_PORT_CTRL_MIRROR_TX, 0);</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>return 0;</div><div>+}</div><div>+</div><div>+static int</div><div>+ar7240_get_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>     struct switch_val *val)</div><div>+{</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>struct ar7240sw *as = sw_to_ar7240(dev);</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>struct mii_bus *mii = as->mii_bus;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>u32 ctrl;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>int port = val->port_vlan;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>if (port >= dev->ports)</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>return -EINVAL;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>ctrl = ar7240sw_reg_read(mii, AR7240_REG_PORT_CTRL(port));</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>if ((ctrl & AR7240_PORT_CTRL_MIRROR_TX) == AR7240_PORT_CTRL_MIRROR_TX)</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">            </span>val->value.i = 1;</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>else</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">          </span>val->value.i = 0;</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>return 0;</div><div>+}</div><div>+</div><div> static struct switch_attr ar7240_globals[] = {</div><div> <span class="gmail-Apple-tab-span" style="white-space:pre">    </span>{</div><div> <span class="gmail-Apple-tab-span" style="white-space:pre">            </span>.type = SWITCH_TYPE_INT,</div><div>@@ -1022,9 +1151,34 @@ static struct switch_attr ar7240_globals[] = {</div><div> <span class="gmail-Apple-tab-span" style="white-space:pre">         </span>.get = ar7240_get_vlan,</div><div> <span class="gmail-Apple-tab-span" style="white-space:pre">              </span>.max = 1</div><div> <span class="gmail-Apple-tab-span" style="white-space:pre">     </span>},</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>{</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">             </span>.type = SWITCH_TYPE_INT,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>.name = "mirror_monitor_port",</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>.description = "Mirror monitor port",</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">               </span>.set = ar7240_set_mirror_monitor_port,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">                </span>.get = ar7240_get_mirror_monitor_port,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">                </span>.max = 15</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>},</div><div> };</div><div> </div><div> static struct switch_attr ar7240_port[] = {</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>{</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">             </span>.type = SWITCH_TYPE_INT,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>.name = "enable_mirror_rx",</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>.description = "Enable mirroring of RX packets",</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">            </span>.set = ar7240_set_mirror_rx,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">          </span>.get = ar7240_get_mirror_rx,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">          </span>.max = 1</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>},</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>{</div><div>+</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">             </span>.type = SWITCH_TYPE_INT,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">              </span>.name = "enable_mirror_tx",</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">         </span>.description = "Enable mirroring of TX packets",</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">            </span>.set = ar7240_set_mirror_tx,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">          </span>.get = ar7240_get_mirror_tx,</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">          </span>.max = 1</div><div>+<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>},</div><div> };</div><div> </div><div> static struct switch_attr ar7240_vlan[] = {</div><div>-- </div><div>1.8.3.1</div><div><br></div></div>