Changeset 40777


Ignore:
Timestamp:
2014-05-19T17:48:18+02:00 (4 years ago)
Author:
jow
Message:

ar71xx: Fix tagged+untagged operation on AR8327N (#12181)

Replace the global "vlan_tagged" variable with an array storing the
tagging state per vlan.

The code was taken from #12181, tested and cleaned up by Saverio Proto
with additional bug fixes supplied by Álvaro Fernández.

Tested-by: Jo-Philipp Wich <jow@…>
Signed-off-by: Saverio Proto <zioproto@…>
Signed-off-by: Álvaro Fernández <noltari@…>

File:
1 edited

Legend:

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

    r39338 r40777  
    7474        void (*init_globals)(struct ar8xxx_priv *priv); 
    7575        void (*init_port)(struct ar8xxx_priv *priv, int port); 
    76         void (*setup_port)(struct ar8xxx_priv *priv, int port, u32 egress, 
    77                            u32 ingress, u32 members, u32 pvid); 
     76        void (*setup_port)(struct ar8xxx_priv *priv, int port, u32 members); 
    7877        u32 (*read_port_status)(struct ar8xxx_priv *priv, int port); 
    7978        int (*atu_flush)(struct ar8xxx_priv *priv); 
    8079        void (*vtu_flush)(struct ar8xxx_priv *priv); 
    81         void (*vtu_load_vlan)(struct ar8xxx_priv *priv, u32 vid, u32 port_mask); 
     80        void (*vtu_load_vlan)(struct ar8xxx_priv *priv, u32 vlan); 
    8281 
    8382        const struct ar8xxx_mib_desc *mib_decs; 
     
    113112}; 
    114113 
     114struct ar8216_data { 
     115        u8 vlan_tagged; 
     116}; 
     117 
    115118struct ar8327_data { 
     119        u8 vlan_tagged[AR8X16_MAX_VLANS]; 
    116120        u32 port0_status; 
    117121        u32 port6_status; 
     
    139143        const struct ar8xxx_chip *chip; 
    140144        union { 
     145                struct ar8216_data ar8216; 
    141146                struct ar8327_data ar8327; 
    142147        } chip_data; 
     
    160165        u16 vlan_id[AR8X16_MAX_VLANS]; 
    161166        u8 vlan_table[AR8X16_MAX_VLANS]; 
    162         u8 vlan_tagged; 
    163167        u16 pvid[AR8X16_MAX_PORTS]; 
    164168 
     
    642646 
    643647        /* no need to fix up packets coming from a tagged source */ 
    644         if (priv->vlan_tagged & (1 << port)) 
     648        if (priv->chip_data.ar8216.vlan_tagged & BIT(port)) 
    645649                return; 
    646650 
     
    696700 
    697701static void 
    698 ar8216_vtu_load_vlan(struct ar8xxx_priv *priv, u32 vid, u32 port_mask) 
     702ar8216_vtu_load_vlan(struct ar8xxx_priv *priv, u32 vlan) 
    699703{ 
    700704        u32 op; 
    701705 
     706        u32 vid = priv->vlan_id[vlan]; 
     707        u32 port_mask = priv->vlan_table[vlan]; 
     708 
    702709        op = AR8216_VTU_OP_LOAD | (vid << AR8216_VTU_VID_S); 
     710 
    703711        ar8216_vtu_op(priv, op, port_mask); 
    704712} 
     
    723731 
    724732static void 
    725 ar8216_setup_port(struct ar8xxx_priv *priv, int port, u32 egress, u32 ingress, 
    726                   u32 members, u32 pvid) 
     733ar8216_setup_port(struct ar8xxx_priv *priv, int port, u32 members) 
    727734{ 
    728735        u32 header; 
     736        u32 egress, ingress; 
     737        u32 pvid; 
     738 
     739        if (priv->vlan) { 
     740                pvid = priv->vlan_id[priv->pvid[port]]; 
     741                if (priv->chip_data.ar8216.vlan_tagged & BIT(port)) 
     742                        egress = AR8216_OUT_ADD_VLAN; 
     743                else 
     744                        egress = AR8216_OUT_STRIP_VLAN; 
     745                ingress = AR8216_IN_SECURE; 
     746        } else { 
     747                pvid = port; 
     748                egress = AR8216_OUT_KEEP; 
     749                ingress = AR8216_IN_PORT_ONLY; 
     750        } 
     751 
     752 
    729753 
    730754        if (chip_is_ar8216(priv) && priv->vlan && port == AR8216_PORT_CPU) 
     
    808832 
    809833static void 
    810 ar8236_setup_port(struct ar8xxx_priv *priv, int port, u32 egress, u32 ingress, 
    811                   u32 members, u32 pvid) 
    812 { 
     834ar8236_setup_port(struct ar8xxx_priv *priv, int port, u32 members) 
     835{ 
     836        u32 egress, ingress; 
     837        u32 pvid; 
     838 
     839        if (priv->vlan) { 
     840                pvid = priv->vlan_id[priv->pvid[port]]; 
     841                if (priv->chip_data.ar8216.vlan_tagged & BIT(port)) 
     842                        egress = AR8216_OUT_ADD_VLAN; 
     843                else 
     844                        egress = AR8216_OUT_STRIP_VLAN; 
     845                ingress = AR8216_IN_SECURE; 
     846        } else { 
     847                pvid = port; 
     848                egress = AR8216_OUT_KEEP; 
     849                ingress = AR8216_IN_PORT_ONLY; 
     850        } 
     851 
    813852        ar8xxx_rmw(priv, AR8216_REG_PORT_CTRL(port), 
    814853                   AR8216_PORT_CTRL_LEARN | AR8216_PORT_CTRL_VLAN_MODE | 
     
    16971736 
    16981737static void 
    1699 ar8327_vtu_load_vlan(struct ar8xxx_priv *priv, u32 vid, u32 port_mask) 
    1700 { 
    1701         u32 op; 
    1702         u32 val; 
     1738ar8327_vtu_load_vlan(struct ar8xxx_priv *priv, u32 vlan) 
     1739{ 
     1740        u32 op, val; 
    17031741        int i; 
     1742 
     1743        u32 vid = priv->vlan_id[vlan]; 
     1744        u32 port_mask = priv->vlan_table[vlan]; 
     1745        u32 tagged = priv->chip_data.ar8327.vlan_tagged[vlan]; 
     1746 
    17041747 
    17051748        op = AR8327_VTU_FUNC1_OP_LOAD | (vid << AR8327_VTU_FUNC1_VID_S); 
     
    17121755                else if (priv->vlan == 0) 
    17131756                        mode = AR8327_VTU_FUNC0_EG_MODE_KEEP; 
    1714                 else if (priv->vlan_tagged & BIT(i)) 
     1757                else if (tagged & BIT(i)) 
    17151758                        mode = AR8327_VTU_FUNC0_EG_MODE_TAG; 
    17161759                else 
     
    17231766 
    17241767static void 
    1725 ar8327_setup_port(struct ar8xxx_priv *priv, int port, u32 egress, u32 ingress, 
    1726                   u32 members, u32 pvid) 
    1727 { 
     1768ar8327_setup_port(struct ar8xxx_priv *priv, int port, u32 members) 
     1769{ 
     1770        u32 ingress, mode; 
     1771        u32 pvid; 
     1772 
    17281773        u32 t; 
    1729         u32 mode; 
     1774 
     1775        if (priv->vlan) { 
     1776                pvid = priv->vlan_id[priv->pvid[port]]; 
     1777                mode = AR8327_PORT_VLAN1_OUT_MODE_UNMOD; 
     1778                ingress = AR8216_IN_SECURE; 
     1779        } else { 
     1780                pvid = port; 
     1781                mode = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH; 
     1782                ingress = AR8216_IN_PORT_ONLY; 
     1783        } 
    17301784 
    17311785        t = pvid << AR8327_PORT_VLAN0_DEF_SVID_S; 
    17321786        t |= pvid << AR8327_PORT_VLAN0_DEF_CVID_S; 
    17331787        priv->write(priv, AR8327_REG_PORT_VLAN0(port), t); 
    1734  
    1735         mode = AR8327_PORT_VLAN1_OUT_MODE_UNMOD; 
    1736         switch (egress) { 
    1737         case AR8216_OUT_KEEP: 
    1738                 mode = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH; 
    1739                 break; 
    1740         case AR8216_OUT_STRIP_VLAN: 
    1741                 mode = AR8327_PORT_VLAN1_OUT_MODE_UNTAG; 
    1742                 break; 
    1743         case AR8216_OUT_ADD_VLAN: 
    1744                 mode = AR8327_PORT_VLAN1_OUT_MODE_TAG; 
    1745                 break; 
    1746         } 
    17471788 
    17481789        t = AR8327_PORT_VLAN1_PORT_VLAN_PROP; 
     
    18431884 
    18441885static int 
    1845 ar8xxx_sw_get_ports(struct switch_dev *dev, struct switch_val *val) 
    1846 { 
    1847         struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
    1848         u8 ports = priv->vlan_table[val->port_vlan]; 
     1886ar8xxx_sw_get_ports(struct switch_val *val, int ports, u8 port_mask, u8 tagged) 
     1887{ 
    18491888        int i; 
    1850  
    18511889        val->len = 0; 
    1852         for (i = 0; i < dev->ports; i++) { 
     1890        for (i = 0; i < ports; i++) { 
    18531891                struct switch_port *p; 
    18541892 
    1855                 if (!(ports & (1 << i))) 
     1893                if (!(port_mask & BIT(i))) 
    18561894                        continue; 
    18571895 
    18581896                p = &val->value.ports[val->len++]; 
    18591897                p->id = i; 
    1860                 if (priv->vlan_tagged & (1 << i)) 
    1861                         p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); 
     1898                if (tagged & BIT(i)) 
     1899                        p->flags = BIT(SWITCH_PORT_FLAG_TAGGED); 
    18621900                else 
    18631901                        p->flags = 0; 
     
    18671905 
    18681906static int 
    1869 ar8xxx_sw_set_ports(struct switch_dev *dev, struct switch_val *val) 
     1907ar8216_sw_get_ports(struct switch_dev *dev, struct switch_val *val) 
     1908{ 
     1909        int ports = dev->ports; 
     1910        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
     1911        u8 port_mask = priv->vlan_table[val->port_vlan]; 
     1912        u8 tagged = priv->chip_data.ar8216.vlan_tagged; 
     1913 
     1914        return ar8xxx_sw_get_ports(val, ports, port_mask, tagged); 
     1915} 
     1916 
     1917static int 
     1918ar8327_sw_get_ports(struct switch_dev *dev, struct switch_val *val) 
     1919{ 
     1920        int ports = dev->ports; 
     1921        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
     1922        u8 port_mask = priv->vlan_table[val->port_vlan]; 
     1923        u8 tagged = priv->chip_data.ar8327.vlan_tagged[val->port_vlan]; 
     1924 
     1925        return ar8xxx_sw_get_ports(val, ports, port_mask, tagged); 
     1926} 
     1927 
     1928static int 
     1929ar8216_sw_set_ports(struct switch_dev *dev, struct switch_val *val) 
    18701930{ 
    18711931        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
    18721932        u8 *vt = &priv->vlan_table[val->port_vlan]; 
     1933        u8 *tagged = &priv->chip_data.ar8216.vlan_tagged; 
     1934 
    18731935        int i, j; 
    18741936 
     
    18771939                struct switch_port *p = &val->value.ports[i]; 
    18781940 
    1879                 if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) { 
    1880                         priv->vlan_tagged |= (1 << p->id); 
     1941                if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED)) { 
     1942 
     1943                        /* if port was untagged before then 
     1944                         * remove him from other vlans */ 
     1945                        if(*tagged & BIT(p->id)){ 
     1946                                for (j = 0; j < AR8X16_MAX_VLANS; j++) { 
     1947                                        if (j == val->port_vlan) 
     1948                                                continue; 
     1949 
     1950                                        priv->vlan_table[j] &= ~(BIT(p->id)); 
     1951                                } 
     1952                        } 
     1953 
     1954                        *tagged |= BIT(p->id); 
    18811955                } else { 
    1882                         priv->vlan_tagged &= ~(1 << p->id); 
     1956                        *tagged &= ~(BIT(p->id)); 
    18831957                        priv->pvid[p->id] = val->port_vlan; 
    18841958 
     
    18881962                                if (j == val->port_vlan) 
    18891963                                        continue; 
    1890                                 priv->vlan_table[j] &= ~(1 << p->id); 
     1964 
     1965                                priv->vlan_table[j] &= ~(BIT(p->id)); 
    18911966                        } 
    18921967                } 
    18931968 
    1894                 *vt |= 1 << p->id; 
     1969                *vt |= BIT(p->id); 
     1970        } 
     1971        return 0; 
     1972} 
     1973 
     1974static int 
     1975ar8327_sw_set_ports(struct switch_dev *dev, struct switch_val *val) 
     1976{ 
     1977        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); 
     1978        u8 *vt = &priv->vlan_table[val->port_vlan]; 
     1979        u8 *vlan_tagged = priv->chip_data.ar8327.vlan_tagged; 
     1980        u8 *tagged = &vlan_tagged[val->port_vlan]; 
     1981 
     1982        int i, j; 
     1983 
     1984        *vt = 0; 
     1985        *tagged = 0; 
     1986        for (i = 0; i < val->len; i++) { 
     1987                struct switch_port *p = &val->value.ports[i]; 
     1988 
     1989                if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED)) { 
     1990                        *tagged |= BIT(p->id); 
     1991                } else { 
     1992                        priv->pvid[p->id] = val->port_vlan; 
     1993                } 
     1994 
     1995                *vt |= BIT(p->id); 
    18951996        } 
    18961997        return 0; 
     
    20112112 
    20122113                        for (i = 0; i < dev->ports; i++) { 
    2013                                 u8 mask = (1 << i); 
     2114                                u8 mask = BIT(i); 
    20142115                                if (vp & mask) 
    20152116                                        portmask[i] |= vp & ~mask; 
    20162117                        } 
    2017  
    2018                         priv->chip->vtu_load_vlan(priv, priv->vlan_id[j], 
    2019                                                  priv->vlan_table[j]); 
     2118                        priv->chip->vtu_load_vlan(priv, j); 
    20202119                } 
    20212120        } else { 
     
    20262125                                continue; 
    20272126 
    2028                         portmask[i] = 1 << AR8216_PORT_CPU; 
    2029                         portmask[AR8216_PORT_CPU] |= (1 << i); 
     2127                        portmask[i] = BIT(AR8216_PORT_CPU); 
     2128                        portmask[AR8216_PORT_CPU] |= BIT(i); 
    20302129                } 
    20312130        } 
     
    20332132        /* update the port destination mask registers and tag settings */ 
    20342133        for (i = 0; i < dev->ports; i++) { 
    2035                 int egress, ingress; 
    2036                 int pvid; 
    2037  
    2038                 if (priv->vlan) { 
    2039                         pvid = priv->vlan_id[priv->pvid[i]]; 
    2040                         if (priv->vlan_tagged & (1 << i)) 
    2041                                 egress = AR8216_OUT_ADD_VLAN; 
    2042                         else 
    2043                                 egress = AR8216_OUT_STRIP_VLAN; 
    2044                         ingress = AR8216_IN_SECURE; 
    2045                 } else { 
    2046                         pvid = i; 
    2047                         egress = AR8216_OUT_KEEP; 
    2048                         ingress = AR8216_IN_PORT_ONLY; 
    2049                 } 
    2050  
    2051                 priv->chip->setup_port(priv, i, egress, ingress, portmask[i], 
    2052                                        pvid); 
     2134                priv->chip->setup_port(priv, i, portmask[i]); 
    20532135        } 
    20542136 
     
    24342516        .get_port_pvid = ar8xxx_sw_get_pvid, 
    24352517        .set_port_pvid = ar8xxx_sw_set_pvid, 
    2436         .get_vlan_ports = ar8xxx_sw_get_ports, 
    2437         .set_vlan_ports = ar8xxx_sw_set_ports, 
     2518        .get_vlan_ports = ar8216_sw_get_ports, 
     2519        .set_vlan_ports = ar8216_sw_set_ports, 
    24382520        .apply_config = ar8xxx_sw_hw_apply, 
    24392521        .reset_switch = ar8xxx_sw_reset_switch, 
     
    24562538        .get_port_pvid = ar8xxx_sw_get_pvid, 
    24572539        .set_port_pvid = ar8xxx_sw_set_pvid, 
    2458         .get_vlan_ports = ar8xxx_sw_get_ports, 
    2459         .set_vlan_ports = ar8xxx_sw_set_ports, 
     2540        .get_vlan_ports = ar8327_sw_get_ports, 
     2541        .set_vlan_ports = ar8327_sw_set_ports, 
    24602542        .apply_config = ar8xxx_sw_hw_apply, 
    24612543        .reset_switch = ar8xxx_sw_reset_switch, 
Note: See TracChangeset for help on using the changeset viewer.