Changeset 36713


Ignore:
Timestamp:
2013-05-24T15:10:22+02:00 (5 years ago)
Author:
luka
Message:

generic: ar8216: add port mirroring

Tested on Buffalo WZR-600DHP with ar8316 switch. Commands used to mirror both
RX and TX traffic from LAN port 1 to LAN port 4:

$ swconfig dev switch0 set enable_mirror_rx 1
$ swconfig dev switch0 set enable_mirror_tx 1
$ swconfig dev switch0 set mirror_monitor_port 4
$ swconfig dev switch0 set mirror_source_port 1

Signed-off-by: Colin Leitner <colin.leitner@…>
Tested-by: Luka Perkov <luka@…>

Location:
trunk/target/linux/generic/files/drivers/net/phy
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/generic/files/drivers/net/phy/ar8216.c

    r36630 r36713  
    121121        u8 vlan_tagged; 
    122122        u16 pvid[AR8X16_MAX_PORTS]; 
     123 
     124        /* mirroring */ 
     125        bool mirror_rx; 
     126        bool mirror_tx; 
     127        int source_port; 
     128        int monitor_port; 
    123129}; 
    124130 
     
    14581464} 
    14591465 
     1466static void 
     1467ar8327_set_mirror_regs(struct ar8xxx_priv *priv) 
     1468{ 
     1469        int port; 
     1470  
     1471        /* reset all mirror registers */ 
     1472        ar8xxx_rmw(priv, AR8327_REG_FWD_CTRL0, 
     1473                   AR8327_FWD_CTRL0_MIRROR_PORT, 
     1474                   (0xF << AR8327_FWD_CTRL0_MIRROR_PORT_S)); 
     1475        for (port = 0; port < AR8327_NUM_PORTS; port++) { 
     1476                ar8xxx_rmw(priv, AR8327_REG_PORT_LOOKUP(port), 
     1477                           AR8327_PORT_LOOKUP_ING_MIRROR_EN, 
     1478                           0); 
     1479 
     1480                ar8xxx_rmw(priv, AR8327_REG_PORT_HOL_CTRL1(port), 
     1481                           AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN, 
     1482                           0); 
     1483        } 
     1484 
     1485        /* now enable mirroring if necessary */ 
     1486        if (priv->source_port >= AR8327_NUM_PORTS || 
     1487            priv->monitor_port >= AR8327_NUM_PORTS || 
     1488            priv->source_port == priv->monitor_port) { 
     1489                return; 
     1490        } 
     1491 
     1492        ar8xxx_rmw(priv, AR8327_REG_FWD_CTRL0, 
     1493                   AR8327_FWD_CTRL0_MIRROR_PORT, 
     1494                   (priv->monitor_port << AR8327_FWD_CTRL0_MIRROR_PORT_S)); 
     1495 
     1496        if (priv->mirror_rx) 
     1497                ar8xxx_rmw(priv, AR8327_REG_PORT_LOOKUP(priv->source_port), 
     1498                           AR8327_PORT_LOOKUP_ING_MIRROR_EN, 
     1499                           AR8327_PORT_LOOKUP_ING_MIRROR_EN); 
     1500 
     1501        if (priv->mirror_tx) 
     1502                ar8xxx_rmw(priv, AR8327_REG_PORT_HOL_CTRL1(priv->source_port), 
     1503                           AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN, 
     1504                           AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN); 
     1505} 
     1506 
     1507static void 
     1508ar8216_set_mirror_regs(struct ar8xxx_priv *priv) 
     1509{ 
     1510        int port; 
     1511 
     1512        /* reset all mirror registers */ 
     1513        ar8xxx_rmw(priv, AR8216_REG_GLOBAL_CPUPORT, 
     1514                   AR8216_GLOBAL_CPUPORT_MIRROR_PORT, 
     1515                   (0xF << AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S)); 
     1516        for (port = 0; port < AR8216_NUM_PORTS; port++) { 
     1517                ar8xxx_rmw(priv, AR8216_REG_PORT_CTRL(port), 
     1518                           AR8216_PORT_CTRL_MIRROR_RX, 
     1519                           0); 
     1520 
     1521                ar8xxx_rmw(priv, AR8216_REG_PORT_CTRL(port), 
     1522                           AR8216_PORT_CTRL_MIRROR_TX, 
     1523                           0); 
     1524        } 
     1525 
     1526        /* now enable mirroring if necessary */ 
     1527        if (priv->source_port >= AR8216_NUM_PORTS || 
     1528            priv->monitor_port >= AR8216_NUM_PORTS || 
     1529            priv->source_port == priv->monitor_port) { 
     1530                return; 
     1531        } 
     1532 
     1533        ar8xxx_rmw(priv, AR8216_REG_GLOBAL_CPUPORT, 
     1534                   AR8216_GLOBAL_CPUPORT_MIRROR_PORT, 
     1535                   (priv->monitor_port << AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S)); 
     1536 
     1537        if (priv->mirror_rx) 
     1538                ar8xxx_rmw(priv, AR8216_REG_PORT_CTRL(priv->source_port), 
     1539                           AR8216_PORT_CTRL_MIRROR_RX, 
     1540                           AR8216_PORT_CTRL_MIRROR_RX); 
     1541 
     1542        if (priv->mirror_tx) 
     1543                ar8xxx_rmw(priv, AR8216_REG_PORT_CTRL(priv->source_port), 
     1544                           AR8216_PORT_CTRL_MIRROR_TX, 
     1545                           AR8216_PORT_CTRL_MIRROR_TX); 
     1546} 
     1547 
     1548static void 
     1549ar8xxx_set_mirror_regs(struct ar8xxx_priv *priv) 
     1550{ 
     1551        if (chip_is_ar8327(priv)) { 
     1552                ar8327_set_mirror_regs(priv); 
     1553        } else { 
     1554                ar8216_set_mirror_regs(priv); 
     1555        } 
     1556} 
     1557 
    14601558static int 
    14611559ar8xxx_sw_hw_apply(struct switch_dev *dev) 
     
    15211619                                       pvid); 
    15221620        } 
     1621         
     1622        ar8xxx_set_mirror_regs(priv); 
     1623         
    15231624        mutex_unlock(&priv->reg_mutex); 
    15241625        return 0; 
     
    15421643                priv->chip->init_port(priv, i); 
    15431644 
     1645        priv->mirror_rx = false; 
     1646        priv->mirror_tx = false; 
     1647        priv->source_port = 0; 
     1648        priv->monitor_port = 0; 
     1649         
    15441650        priv->chip->init_globals(priv); 
     1651 
    15451652        mutex_unlock(&priv->reg_mutex); 
    15461653 
     
    15741681        mutex_unlock(&priv->mib_lock); 
    15751682        return ret; 
     1683} 
     1684 
     1685static int 
     1686ar8xxx_sw_set_mirror_rx_enable(struct switch_dev *dev, 
     1687                               const struct switch_attr *attr, 
     1688                               struct switch_val *val) 
     1689{ 
     1690        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
     1691         
     1692        mutex_lock(&priv->reg_mutex); 
     1693        priv->mirror_rx = !!val->value.i; 
     1694        ar8xxx_set_mirror_regs(priv); 
     1695        mutex_unlock(&priv->reg_mutex); 
     1696 
     1697        return 0; 
     1698} 
     1699 
     1700static int 
     1701ar8xxx_sw_get_mirror_rx_enable(struct switch_dev *dev, 
     1702                               const struct switch_attr *attr, 
     1703                               struct switch_val *val) 
     1704{ 
     1705        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
     1706        val->value.i = priv->mirror_rx; 
     1707        return 0; 
     1708} 
     1709 
     1710static int 
     1711ar8xxx_sw_set_mirror_tx_enable(struct switch_dev *dev, 
     1712                               const struct switch_attr *attr, 
     1713                               struct switch_val *val) 
     1714{ 
     1715        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
     1716 
     1717        mutex_lock(&priv->reg_mutex); 
     1718        priv->mirror_tx = !!val->value.i; 
     1719        ar8xxx_set_mirror_regs(priv); 
     1720        mutex_unlock(&priv->reg_mutex); 
     1721 
     1722        return 0; 
     1723} 
     1724 
     1725static int 
     1726ar8xxx_sw_get_mirror_tx_enable(struct switch_dev *dev, 
     1727                               const struct switch_attr *attr, 
     1728                               struct switch_val *val) 
     1729{ 
     1730        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
     1731        val->value.i = priv->mirror_tx; 
     1732        return 0; 
     1733} 
     1734 
     1735static int 
     1736ar8xxx_sw_set_mirror_monitor_port(struct switch_dev *dev, 
     1737                                  const struct switch_attr *attr, 
     1738                                  struct switch_val *val) 
     1739{ 
     1740        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
     1741         
     1742        mutex_lock(&priv->reg_mutex); 
     1743        priv->monitor_port = val->value.i; 
     1744        ar8xxx_set_mirror_regs(priv); 
     1745        mutex_unlock(&priv->reg_mutex); 
     1746 
     1747        return 0; 
     1748} 
     1749 
     1750static int 
     1751ar8xxx_sw_get_mirror_monitor_port(struct switch_dev *dev, 
     1752                                  const struct switch_attr *attr, 
     1753                                  struct switch_val *val) 
     1754{ 
     1755        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
     1756        val->value.i = priv->monitor_port; 
     1757        return 0; 
     1758} 
     1759 
     1760static int 
     1761ar8xxx_sw_set_mirror_source_port(struct switch_dev *dev, 
     1762                                 const struct switch_attr *attr, 
     1763                                 struct switch_val *val) 
     1764{ 
     1765        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
     1766         
     1767        mutex_lock(&priv->reg_mutex); 
     1768        priv->source_port = val->value.i; 
     1769        ar8xxx_set_mirror_regs(priv); 
     1770        mutex_unlock(&priv->reg_mutex); 
     1771 
     1772        return 0; 
     1773} 
     1774 
     1775static int 
     1776ar8xxx_sw_get_mirror_source_port(struct switch_dev *dev, 
     1777                                 const struct switch_attr *attr, 
     1778                                 struct switch_val *val) 
     1779{ 
     1780        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
     1781        val->value.i = priv->source_port; 
     1782        return 0; 
    15761783} 
    15771784 
     
    16691876                .set = ar8xxx_sw_set_reset_mibs, 
    16701877        }, 
    1671  
     1878        { 
     1879                .type = SWITCH_TYPE_INT, 
     1880                .name = "enable_mirror_rx", 
     1881                .description = "Enable mirroring of RX packets", 
     1882                .set = ar8xxx_sw_set_mirror_rx_enable, 
     1883                .get = ar8xxx_sw_get_mirror_rx_enable, 
     1884                .max = 1 
     1885        }, 
     1886        { 
     1887                .type = SWITCH_TYPE_INT, 
     1888                .name = "enable_mirror_tx", 
     1889                .description = "Enable mirroring of TX packets", 
     1890                .set = ar8xxx_sw_set_mirror_tx_enable, 
     1891                .get = ar8xxx_sw_get_mirror_tx_enable, 
     1892                .max = 1 
     1893        }, 
     1894        { 
     1895                .type = SWITCH_TYPE_INT, 
     1896                .name = "mirror_monitor_port", 
     1897                .description = "Mirror monitor port", 
     1898                .set = ar8xxx_sw_set_mirror_monitor_port, 
     1899                .get = ar8xxx_sw_get_mirror_monitor_port, 
     1900                .max = AR8216_NUM_PORTS - 1  
     1901        }, 
     1902        { 
     1903                .type = SWITCH_TYPE_INT, 
     1904                .name = "mirror_source_port", 
     1905                .description = "Mirror source port", 
     1906                .set = ar8xxx_sw_set_mirror_source_port, 
     1907                .get = ar8xxx_sw_get_mirror_source_port, 
     1908                .max = AR8216_NUM_PORTS - 1 
     1909        }, 
     1910}; 
     1911 
     1912static struct switch_attr ar8327_sw_attr_globals[] = { 
     1913        { 
     1914                .type = SWITCH_TYPE_INT, 
     1915                .name = "enable_vlan", 
     1916                .description = "Enable VLAN mode", 
     1917                .set = ar8xxx_sw_set_vlan, 
     1918                .get = ar8xxx_sw_get_vlan, 
     1919                .max = 1 
     1920        }, 
     1921        { 
     1922                .type = SWITCH_TYPE_NOVAL, 
     1923                .name = "reset_mibs", 
     1924                .description = "Reset all MIB counters", 
     1925                .set = ar8xxx_sw_set_reset_mibs, 
     1926        }, 
     1927        { 
     1928                .type = SWITCH_TYPE_INT, 
     1929                .name = "enable_mirror_rx", 
     1930                .description = "Enable mirroring of RX packets", 
     1931                .set = ar8xxx_sw_set_mirror_rx_enable, 
     1932                .get = ar8xxx_sw_get_mirror_rx_enable, 
     1933                .max = 1 
     1934        }, 
     1935        { 
     1936                .type = SWITCH_TYPE_INT, 
     1937                .name = "enable_mirror_tx", 
     1938                .description = "Enable mirroring of TX packets", 
     1939                .set = ar8xxx_sw_set_mirror_tx_enable, 
     1940                .get = ar8xxx_sw_get_mirror_tx_enable, 
     1941                .max = 1 
     1942        }, 
     1943        { 
     1944                .type = SWITCH_TYPE_INT, 
     1945                .name = "mirror_monitor_port", 
     1946                .description = "Mirror monitor port", 
     1947                .set = ar8xxx_sw_set_mirror_monitor_port, 
     1948                .get = ar8xxx_sw_get_mirror_monitor_port, 
     1949                .max = AR8327_NUM_PORTS - 1  
     1950        }, 
     1951        { 
     1952                .type = SWITCH_TYPE_INT, 
     1953                .name = "mirror_source_port", 
     1954                .description = "Mirror source port", 
     1955                .set = ar8xxx_sw_set_mirror_source_port, 
     1956                .get = ar8xxx_sw_get_mirror_source_port, 
     1957                .max = AR8327_NUM_PORTS - 1 
     1958        }, 
    16721959}; 
    16731960 
     
    17212008}; 
    17222009 
     2010static const struct switch_dev_ops ar8327_sw_ops = { 
     2011        .attr_global = { 
     2012                .attr = ar8327_sw_attr_globals, 
     2013                .n_attr = ARRAY_SIZE(ar8327_sw_attr_globals), 
     2014        }, 
     2015        .attr_port = { 
     2016                .attr = ar8xxx_sw_attr_port, 
     2017                .n_attr = ARRAY_SIZE(ar8xxx_sw_attr_port), 
     2018        }, 
     2019        .attr_vlan = { 
     2020                .attr = ar8xxx_sw_attr_vlan, 
     2021                .n_attr = ARRAY_SIZE(ar8xxx_sw_attr_vlan), 
     2022        }, 
     2023        .get_port_pvid = ar8xxx_sw_get_pvid, 
     2024        .set_port_pvid = ar8xxx_sw_set_pvid, 
     2025        .get_vlan_ports = ar8xxx_sw_get_ports, 
     2026        .set_vlan_ports = ar8xxx_sw_set_ports, 
     2027        .apply_config = ar8xxx_sw_hw_apply, 
     2028        .reset_switch = ar8xxx_sw_reset_switch, 
     2029        .get_port_link = ar8xxx_sw_get_port_link, 
     2030}; 
     2031 
    17232032static int 
    17242033ar8xxx_id_chip(struct ar8xxx_priv *priv) 
     
    19012210                swdev->vlans = AR8X16_MAX_VLANS; 
    19022211                swdev->ports = AR8327_NUM_PORTS; 
     2212                swdev->ops = &ar8327_sw_ops; 
    19032213        } else { 
    19042214                swdev->name = "Atheros AR8216"; 
  • trunk/target/linux/generic/files/drivers/net/phy/ar8216.h

    r35539 r36713  
    105105#define   AR8216_MIB_FUNC_CAPTURE       0x3 
    106106#define   AR8236_MIB_EN                 BIT(30) 
     107 
     108#define AR8216_REG_GLOBAL_CPUPORT               0x0078 
     109#define   AR8216_GLOBAL_CPUPORT_MIRROR_PORT     BITS(4, 4) 
     110#define   AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S   4 
    107111 
    108112#define AR8216_PORT_OFFSET(_i)          (0x0100 * (_i + 1)) 
     
    434438#define   AR8327_PORT_LOOKUP_STATE_S            16 
    435439#define   AR8327_PORT_LOOKUP_LEARN              BIT(20) 
     440#define   AR8327_PORT_LOOKUP_ING_MIRROR_EN      BIT(25) 
    436441 
    437442#define AR8327_REG_PORT_PRIO(_i)                (0x664 + (_i) * 0xc) 
     443 
     444#define AR8327_REG_PORT_HOL_CTRL1(_i)           (0x974 + (_i) * 0x8) 
     445#define   AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN    BIT(16) 
    438446 
    439447#define AR8327_REG_PORT_STATS_BASE(_i)          (0x1000 + (_i) * 0x100) 
Note: See TracChangeset for help on using the changeset viewer.