Changeset 38323


Ignore:
Timestamp:
2013-10-07T17:02:39+02:00 (4 years ago)
Author:
blogic
Message:

ralink: split mt7530 driver out of the gsw driver

Signed-off-by: John Crispin <blogic@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/ramips/patches-3.10/0111-NET-MIPS-add-ralink-SoC-ethernet-driver.patch

    r37778 r38323  
    4747 create mode 100644 drivers/net/ethernet/ralink/soc_rt3883.c 
    4848 
    49 --- /dev/null 
    50 +++ b/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h 
     49Index: linux-3.10.13/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h 
     50=================================================================== 
     51--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     52+++ linux-3.10.13/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h       2013-10-02 21:40:50.192369358 +0200 
    5153@@ -0,0 +1,27 @@ 
    5254+/* 
     
    7779+ 
    7880+#endif /* _RT305X_ESW_PLATFORM_H */ 
    79 --- a/arch/mips/ralink/rt305x.c 
    80 +++ b/arch/mips/ralink/rt305x.c 
    81 @@ -221,6 +221,7 @@ void __init ralink_clk_init(void) 
     81Index: linux-3.10.13/arch/mips/ralink/rt305x.c 
     82=================================================================== 
     83--- linux-3.10.13.orig/arch/mips/ralink/rt305x.c        2013-10-02 21:12:59.896297955 +0200 
     84+++ linux-3.10.13/arch/mips/ralink/rt305x.c     2013-10-06 13:27:24.076279369 +0200 
     85@@ -221,6 +221,7 @@ 
    8286        } 
    8387  
     
    8791        ralink_clk_add("10000100.timer", wdt_rate); 
    8892        ralink_clk_add("10000120.watchdog", wdt_rate); 
    89 --- a/drivers/net/ethernet/Kconfig 
    90 +++ b/drivers/net/ethernet/Kconfig 
    91 @@ -135,6 +135,7 @@ config ETHOC 
     93Index: linux-3.10.13/drivers/net/ethernet/Kconfig 
     94=================================================================== 
     95--- linux-3.10.13.orig/drivers/net/ethernet/Kconfig     2013-10-02 21:12:59.896297955 +0200 
     96+++ linux-3.10.13/drivers/net/ethernet/Kconfig  2013-10-02 21:40:50.192369358 +0200 
     97@@ -135,6 +135,7 @@ 
    9298 source "drivers/net/ethernet/packetengines/Kconfig" 
    9399 source "drivers/net/ethernet/pasemi/Kconfig" 
     
    97103 source "drivers/net/ethernet/renesas/Kconfig" 
    98104 source "drivers/net/ethernet/rdc/Kconfig" 
    99 --- a/drivers/net/ethernet/Makefile 
    100 +++ b/drivers/net/ethernet/Makefile 
    101 @@ -53,6 +53,7 @@ obj-$(CONFIG_ETHOC) += ethoc.o 
     105Index: linux-3.10.13/drivers/net/ethernet/Makefile 
     106=================================================================== 
     107--- linux-3.10.13.orig/drivers/net/ethernet/Makefile    2013-10-02 21:12:59.896297955 +0200 
     108+++ linux-3.10.13/drivers/net/ethernet/Makefile 2013-10-02 21:40:50.192369358 +0200 
     109@@ -53,6 +53,7 @@ 
    102110 obj-$(CONFIG_NET_PACKET_ENGINE) += packetengines/ 
    103111 obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/ 
     
    107115 obj-$(CONFIG_SH_ETH) += renesas/ 
    108116 obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ 
    109 --- /dev/null 
    110 +++ b/drivers/net/ethernet/ralink/Kconfig 
     117Index: linux-3.10.13/drivers/net/ethernet/ralink/Kconfig 
     118=================================================================== 
     119--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     120+++ linux-3.10.13/drivers/net/ethernet/ralink/Kconfig   2013-10-02 21:40:50.196369356 +0200 
    111121@@ -0,0 +1,31 @@ 
    112122+config NET_RALINK 
     
    141151+       select SWCONFIG 
    142152+endif 
    143 --- /dev/null 
    144 +++ b/drivers/net/ethernet/ralink/Makefile 
     153Index: linux-3.10.13/drivers/net/ethernet/ralink/Makefile 
     154=================================================================== 
     155--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     156+++ linux-3.10.13/drivers/net/ethernet/ralink/Makefile  2013-10-03 23:14:02.777666985 +0200 
    145157@@ -0,0 +1,18 @@ 
    146158+# 
     
    154166+ 
    155167+ralink-eth-$(CONFIG_NET_RALINK_ESW_RT3052)     += esw_rt3052.o 
    156 +ralink-eth-$(CONFIG_NET_RALINK_GSW_MT7620)     += gsw_mt7620a.o 
     168+ralink-eth-$(CONFIG_NET_RALINK_GSW_MT7620)     += gsw_mt7620a.o mt7530.o 
    157169+ 
    158170+ralink-eth-$(CONFIG_SOC_RT288X)                        += soc_rt2880.o 
     
    162174+ 
    163175+obj-$(CONFIG_NET_RALINK)                       += ralink-eth.o 
    164 --- /dev/null 
    165 +++ b/drivers/net/ethernet/ralink/esw_rt3052.c 
     176Index: linux-3.10.13/drivers/net/ethernet/ralink/esw_rt3052.c 
     177=================================================================== 
     178--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     179+++ linux-3.10.13/drivers/net/ethernet/ralink/esw_rt3052.c      2013-10-02 21:40:50.196369356 +0200 
    166180@@ -0,0 +1,1463 @@ 
    167181+/* 
     
    16281642+       platform_driver_unregister(&esw_driver); 
    16291643+} 
    1630 --- /dev/null 
    1631 +++ b/drivers/net/ethernet/ralink/esw_rt3052.h 
     1644Index: linux-3.10.13/drivers/net/ethernet/ralink/esw_rt3052.h 
     1645=================================================================== 
     1646--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     1647+++ linux-3.10.13/drivers/net/ethernet/ralink/esw_rt3052.h      2013-10-02 21:40:50.196369356 +0200 
    16321648@@ -0,0 +1,32 @@ 
    16331649+/* 
     
    16631679+#endif 
    16641680+#endif 
    1665 --- /dev/null 
    1666 +++ b/drivers/net/ethernet/ralink/gsw_mt7620a.c 
    1667 @@ -0,0 +1,1027 @@ 
     1681Index: linux-3.10.13/drivers/net/ethernet/ralink/gsw_mt7620a.c 
     1682=================================================================== 
     1683--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     1684+++ linux-3.10.13/drivers/net/ethernet/ralink/gsw_mt7620a.c     2013-10-04 17:31:46.468886115 +0200 
     1685@@ -0,0 +1,566 @@ 
    16681686+/* 
    16691687+ *   This program is free software; you can redistribute it and/or modify 
     
    17131731+#include "ralink_soc_eth.h" 
    17141732+#include "gsw_mt7620a.h" 
     1733+#include "mt7530.h" 
    17151734+#include "mdio.h" 
    17161735+ 
     
    17431762+ 
    17441763+#define PORT_IRQ_ST_CHG                0x7f 
    1745 + 
    1746 +#define GSW_VLAN_VTCR          0x90 
    1747 +#define GSW_VLAN_VTCR_VID_M    0xfff 
    1748 +#define GSW_VLAN_ID(_x)                (0x100 + (4 * (_x))) 
    1749 +#define GSW_VLAN_ID_VID_S      12 
    1750 +#define GSW_VLAN_ID_VID_M      0xfff 
    1751 + 
    1752 +#define GSW_VAWD1              0x94 
    1753 +#define GSW_VAWD1_VTAG_EN      BIT(28) 
    1754 +#define GSW_VAWD1_PORTM_S      16 
    1755 +#define GSW_VAWD1_PORTM_M      0xff 
    1756 + 
    1757 +#define GSW_VAWD2              0x98 
    1758 +#define GSW_VAWD2_PORTT_S      16 
    1759 +#define GSW_VAWD2_PORTT_M      0xff 
    1760 + 
    1761 +#define GSW_VTIM(_x)           (0x100 + (4 * (_x))) 
    1762 +#define GSW_VTIM_M             0xfff 
    1763 +#define GSW_VTIM_S             12 
    1764 + 
    1765 +#define GSW_REG_PCR(x)         (0x2004 + (x * 0x100)) 
    1766 +#define GSW_REG_PCR_EG_TAG_S   28 
    1767 +#define GSW_REG_PCR_EG_TAG_M   0x3 
    17681764+ 
    17691765+#define SYSCFG1                        0x14 
     
    18001796+}; 
    18011797+ 
    1802 +struct gsw_port { 
    1803 +       bool    disable; 
    1804 +       bool    untag; 
    1805 +       u16     pvid; 
    1806 +}; 
    1807 + 
    1808 +struct gsw_vlan { 
    1809 +       u8      ports; 
    1810 +       u16     vid; 
    1811 +}; 
    1812 + 
    18131798+struct mt7620_gsw { 
    18141799+       struct device           *dev; 
    18151800+       void __iomem            *base; 
    18161801+       int                     irq; 
    1817 + 
    1818 +       struct switch_dev       swdev; 
    1819 +       bool                    global_vlan_enable; 
    1820 +       struct gsw_vlan         vlans[GSW_NUM_VLANS]; 
    1821 +       struct gsw_port         ports[GSW_NUM_PORTS]; 
     1802+       int                     port4; 
    18221803+       long unsigned int       autopoll; 
    1823 +       int                     port4; 
    18241804+}; 
    18251805+ 
     
    18691849+} 
    18701850+ 
    1871 +int mt7620_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val) 
    1872 +{ 
    1873 +       struct fe_priv *priv = bus->priv; 
    1874 +       struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv; 
    1875 + 
    1876 +       return _mt7620_mii_write(gsw, phy_addr, phy_reg, val); 
    1877 +} 
    1878 + 
    1879 +int mt7620_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg) 
    1880 +{ 
    1881 +       struct fe_priv *priv = bus->priv; 
    1882 +       struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv; 
     1851+static u32 _mt7620_mii_read(struct mt7620_gsw *gsw, int phy_addr, int phy_reg) 
     1852+{ 
    18831853+       u32 d; 
    18841854+ 
     
    18971867+ 
    18981868+       return d; 
     1869+} 
     1870+ 
     1871+int mt7620_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val) 
     1872+{ 
     1873+       struct fe_priv *priv = bus->priv; 
     1874+       struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv; 
     1875+ 
     1876+       return _mt7620_mii_write(gsw, phy_addr, phy_reg, val); 
     1877+} 
     1878+ 
     1879+int mt7620_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg) 
     1880+{ 
     1881+       struct fe_priv *priv = bus->priv; 
     1882+       struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv; 
     1883+ 
     1884+       return _mt7620_mii_read(gsw, phy_addr, phy_reg); 
    18991885+} 
    19001886+ 
     
    20422028+               break; 
    20432029+       default: 
    2044 +               dev_err(priv->device, "port %d - invalid phy mode\n", priv->phy->speed[id]); 
     2030+               dev_err(priv->device, "port %d - invalid phy mode\n", id); 
    20452031+               return; 
    20462032+       } 
     
    20572043+       if (priv->phy->phy_fixed[id]) { 
    20582044+               const __be32 *link = priv->phy->phy_fixed[id]; 
    2059 +               int tx_fc = be32_to_cpup(link++); 
    2060 +               int rx_fc = be32_to_cpup(link++); 
     2045+               int tx_fc, rx_fc; 
    20612046+               u32 val = 0; 
    20622047+ 
    20632048+               priv->phy->speed[id] = be32_to_cpup(link++); 
     2049+               tx_fc = be32_to_cpup(link++); 
     2050+               rx_fc = be32_to_cpup(link++); 
    20642051+               priv->phy->duplex[id] = be32_to_cpup(link++); 
    20652052+               priv->link[id] = 1; 
     
    21722159+       gsw_w32(gsw, 0x7f7f7fe0, 0x0010); 
    21732160+ 
    2174 +//     GSW_VAWD2 
    2175 + 
    21762161+       /* setup port 4 */ 
    21772162+       if (gsw->port4 == PORT4_EPHY) { 
     
    21862171+} 
    21872172+ 
    2188 +static int gsw_reset_switch(struct switch_dev *dev) 
    2189 +{ 
    2190 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2191 + 
    2192 +       gsw->global_vlan_enable = 0; 
    2193 +       memset(gsw->ports, 0, sizeof(gsw->ports)); 
    2194 +       memset(gsw->vlans, 0, sizeof(gsw->vlans)); 
    2195 +       gsw_hw_init(gsw); 
    2196 + 
    2197 +       return 0; 
    2198 +} 
    2199 + 
    2200 +static int gsw_get_vlan_enable(struct switch_dev *dev, 
    2201 +                          const struct switch_attr *attr, 
    2202 +                          struct switch_val *val) 
    2203 +{ 
    2204 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2205 + 
    2206 +       val->value.i = gsw->global_vlan_enable; 
    2207 + 
    2208 +       return 0; 
    2209 +} 
    2210 + 
    2211 +static int gsw_set_vlan_enable(struct switch_dev *dev, 
    2212 +                          const struct switch_attr *attr, 
    2213 +                          struct switch_val *val) 
    2214 +{ 
    2215 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2216 + 
    2217 +       gsw->global_vlan_enable = val->value.i != 0; 
    2218 + 
    2219 +       return 0; 
    2220 +} 
    2221 + 
    2222 +static unsigned gsw_get_pvid(struct mt7620_gsw *gsw, unsigned port) 
    2223 +{ 
    2224 +       unsigned s, val; 
    2225 + 
    2226 +       s = GSW_VTIM_S * (port % 2); 
    2227 +       val = gsw_r32(gsw, GSW_VTIM(port / 2)); 
    2228 + 
    2229 +       return (val >> s) & GSW_VTIM_M; 
    2230 +} 
    2231 + 
    2232 +static void gsw_set_pvid(struct mt7620_gsw *gsw, unsigned port, unsigned pvid) 
    2233 +{ 
    2234 +       unsigned s, val; 
    2235 + 
    2236 +       s = GSW_VTIM_S * (port % 2); 
    2237 +       val = gsw_r32(gsw, GSW_VTIM(port / 2)); 
    2238 +       val &= ~(GSW_VTIM_M << s); 
    2239 +       val |= (pvid && GSW_VTIM_M) << s; 
    2240 +       gsw_w32(gsw, val, GSW_VTIM(port / 2)); 
    2241 +} 
    2242 + 
    2243 +static int gsw_get_port_bool(struct switch_dev *dev, 
    2244 +                        const struct switch_attr *attr, 
    2245 +                        struct switch_val *val) 
    2246 +{ 
    2247 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2248 +       int idx = val->port_vlan; 
    2249 + 
    2250 +       if (idx < 0 || idx >= GSW_NUM_PORTS) 
    2251 +               return -EINVAL; 
    2252 + 
    2253 +       switch (attr->id) { 
    2254 +       case GSW_ATTR_PORT_UNTAG: 
    2255 +               return gsw->ports[idx].untag; 
    2256 +       } 
    2257 + 
    2258 +       return -EINVAL; 
    2259 +} 
    2260 + 
    2261 +static int gsw_get_port_pvid(struct switch_dev *dev, int port, int *val) 
    2262 +{ 
    2263 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2264 + 
    2265 +       if (port >= GSW_NUM_PORTS) 
    2266 +               return -EINVAL; 
    2267 + 
    2268 +       *val = gsw_get_pvid(gsw, port); 
    2269 + 
    2270 +       return 0; 
    2271 +} 
    2272 + 
    2273 +static int gsw_set_port_pvid(struct switch_dev *dev, int port, int val) 
    2274 +{ 
    2275 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2276 + 
    2277 +       if (port >= GSW_NUM_PORTS) 
    2278 +               return -EINVAL; 
    2279 + 
    2280 +       gsw->ports[port].pvid = val; 
    2281 + 
    2282 +       return 0; 
    2283 +} 
    2284 + 
    2285 +static void gsw_set_vtcr(struct switch_dev *dev, u32 vid) 
    2286 +{ 
    2287 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2288 +       int retry = 1000; 
    2289 + 
    2290 +       gsw_w32(gsw, 0x80000000 | (BIT(vid) & GSW_VLAN_VTCR_VID_M), GSW_VLAN_VTCR); 
    2291 +       while (retry-- && (gsw_r32(gsw, GSW_VLAN_VTCR) & 0x80000000)) 
    2292 +               ; 
    2293 +} 
    2294 + 
    2295 +static void gsw_apply_vtcr(struct switch_dev *dev, u32 vid) 
    2296 +{ 
    2297 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2298 +       int retry = 1000; 
    2299 + 
    2300 +       gsw_w32(gsw, 0x80001000 | (BIT(vid) & GSW_VLAN_VTCR_VID_M), GSW_VLAN_VTCR); 
    2301 +       while (retry-- && (gsw_r32(gsw, GSW_VLAN_VTCR) & 0x80000000)) 
    2302 +               ; 
    2303 +} 
    2304 + 
    2305 +static unsigned gsw_get_vlan_id(struct mt7620_gsw *gsw, unsigned vlan) 
    2306 +{ 
    2307 +       unsigned s; 
    2308 +       unsigned val; 
    2309 + 
    2310 +       s = GSW_VLAN_ID_VID_S * (vlan % 2); 
    2311 +       val = gsw_r32(gsw, GSW_VLAN_ID(vlan / 2)); 
    2312 +       val = (val >> s) & GSW_VLAN_ID_VID_M; 
    2313 + 
    2314 +       return val; 
    2315 +} 
    2316 + 
    2317 +static void gsw_set_vlan_id(struct mt7620_gsw *gsw, unsigned vlan, unsigned vid) 
    2318 +{ 
    2319 +       unsigned s; 
    2320 +       unsigned val; 
    2321 + 
    2322 +       s = GSW_VLAN_ID_VID_S * (vlan % 2); 
    2323 +       val = gsw_r32(gsw, GSW_VLAN_ID(vlan / 2)); 
    2324 +       val &= ~(GSW_VLAN_ID_VID_M << s); 
    2325 +       val |= (vid << s); 
    2326 +       gsw_w32(gsw, val, GSW_VLAN_ID(vlan / 2)); 
    2327 +} 
    2328 + 
    2329 +static void gsw_vlan_tagging_enable(struct mt7620_gsw *gsw, unsigned vlan, unsigned enable) 
    2330 +{ 
    2331 +       unsigned val; 
    2332 + 
    2333 +       val = gsw_r32(gsw, GSW_VAWD1); 
    2334 +       if (enable) 
    2335 +               val |= GSW_VAWD1_VTAG_EN; 
    2336 +       else 
    2337 +               val &= ~GSW_VAWD1_VTAG_EN; 
    2338 +       gsw_w32(gsw, val, GSW_VAWD1); 
    2339 +} 
    2340 + 
    2341 +static unsigned gsw_get_port_member(struct mt7620_gsw *gsw, unsigned vlan) 
    2342 +{ 
    2343 +       unsigned val; 
    2344 + 
    2345 +       gsw_set_vtcr(&gsw->swdev, vlan); 
    2346 + 
    2347 +       val = gsw_r32(gsw, GSW_VAWD1); 
    2348 +       val = (val >> GSW_VAWD1_PORTM_S) & GSW_VAWD1_PORTM_M; 
    2349 + 
    2350 +       return val; 
    2351 +} 
    2352 + 
    2353 +static void gsw_set_port_member(struct mt7620_gsw *gsw, unsigned vlan, unsigned member) 
    2354 +{ 
    2355 +       unsigned val; 
    2356 + 
    2357 +       val = gsw_r32(gsw, GSW_VAWD1); 
    2358 +       val = ~(GSW_VAWD1_PORTM_M << GSW_VAWD1_PORTM_S); 
    2359 +       val |= (member & GSW_VAWD1_PORTM_M) << GSW_VAWD1_PORTM_S; 
    2360 +        gsw_w32(gsw, val, GSW_VAWD1); 
    2361 +} 
    2362 + 
    2363 +static unsigned gsw_get_port_tag(struct mt7620_gsw *gsw, unsigned port) 
    2364 +{ 
    2365 +       unsigned val; 
    2366 + 
    2367 +       val = gsw_r32(gsw, GSW_REG_PCR(port)); 
    2368 +       val >>= GSW_REG_PCR_EG_TAG_S; 
    2369 +       val &= GSW_REG_PCR_EG_TAG_M; 
    2370 + 
    2371 +       return !!val; 
    2372 +} 
    2373 + 
    2374 +static void gsw_set_port_untag(struct mt7620_gsw *gsw, unsigned port, unsigned untag) 
    2375 +{ 
    2376 +       unsigned val; 
    2377 + 
    2378 +       val = gsw_r32(gsw, GSW_REG_PCR(port)); 
    2379 +       if (!untag) 
    2380 +               untag = 0x2; 
    2381 +       else 
    2382 +               untag = 0; 
    2383 +       val &= ~(GSW_REG_PCR_EG_TAG_M << GSW_REG_PCR_EG_TAG_S); 
    2384 +       val |= (untag & GSW_REG_PCR_EG_TAG_M) << GSW_REG_PCR_EG_TAG_S; 
    2385 +       gsw_w32(gsw, val, GSW_REG_PCR(port)); 
    2386 +} 
    2387 + 
    2388 +static int gsw_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) 
    2389 +{ 
    2390 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2391 +       int vlan_idx = -1; 
    2392 +       u32 member; 
    2393 +       int i; 
    2394 + 
    2395 +       val->len = 0; 
    2396 + 
    2397 +       if (val->port_vlan < 0 || val->port_vlan >= GSW_NUM_VIDS) 
    2398 +               return -EINVAL; 
    2399 + 
    2400 +       /* valid vlan? */ 
    2401 +       for (i = 0; i < GSW_NUM_VLANS; i++) { 
    2402 +               if (gsw_get_vlan_id(gsw, i) != val->port_vlan) 
    2403 +                       continue; 
    2404 +               member = gsw_get_port_member(gsw, i); 
    2405 +               vlan_idx = i; 
    2406 +               break; 
    2407 +       } 
    2408 + 
    2409 +       if (vlan_idx == -1) 
    2410 +               return -EINVAL; 
    2411 + 
    2412 +       for (i = 0; i < GSW_NUM_PORTS; i++) { 
    2413 +               struct switch_port *p; 
    2414 +               int port_mask = 1 << i; 
    2415 + 
    2416 +               if (!(member & port_mask)) 
    2417 +                       continue; 
    2418 + 
    2419 +               p = &val->value.ports[val->len++]; 
    2420 +               p->id = i; 
    2421 +               if (gsw_get_port_tag(gsw, i)) 
    2422 +                       p->flags = 1 << SWITCH_PORT_FLAG_TAGGED; 
    2423 +               else 
    2424 +                       p->flags = 0; 
    2425 +       } 
    2426 + 
    2427 +       return 0; 
    2428 +} 
    2429 + 
    2430 +static int gsw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val) 
    2431 +{ 
    2432 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2433 +       int ports; 
    2434 +       int vlan_idx = -1; 
    2435 +       int i; 
    2436 + 
    2437 +       if (val->port_vlan < 0 || val->port_vlan >= GSW_NUM_VIDS || 
    2438 +                       val->len > GSW_NUM_PORTS) 
    2439 +               return -EINVAL; 
    2440 + 
    2441 +       /* one of the already defined vlans? */ 
    2442 +       for (i = 0; i < GSW_NUM_VLANS; i++) { 
    2443 +               if (gsw->vlans[i].vid == val->port_vlan && 
    2444 +                   gsw->vlans[i].ports) { 
    2445 +                       vlan_idx = i; 
    2446 +                       break; 
    2447 +               } 
    2448 +       } 
    2449 + 
    2450 +       /* select a free slot */ 
    2451 +       for (i = 0; vlan_idx == -1 && i < GSW_NUM_VLANS; i++) { 
    2452 +               if (!gsw->vlans[i].ports) 
    2453 +                       vlan_idx = i; 
    2454 +       } 
    2455 + 
    2456 +       /* bail if all slots are in use */ 
    2457 +       if (vlan_idx == -1) 
    2458 +               return -EINVAL; 
    2459 + 
    2460 +       ports = 0; 
    2461 +       for (i = 0; i < val->len; i++) { 
    2462 +               struct switch_port *p = &val->value.ports[i]; 
    2463 +               int port_mask = 1 << p->id; 
    2464 +               bool untagged = !(p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)); 
    2465 + 
    2466 +               if (p->id >= GSW_NUM_PORTS) 
    2467 +                       return -EINVAL; 
    2468 + 
    2469 +               ports |= port_mask; 
    2470 +               gsw->ports[p->id].untag = untagged; 
    2471 +       } 
    2472 +       gsw->vlans[vlan_idx].ports = ports; 
    2473 +       if (!ports) 
    2474 +               gsw->vlans[vlan_idx].vid = 0xfff; 
    2475 +       else 
    2476 +               gsw->vlans[vlan_idx].vid = val->port_vlan; 
    2477 + 
    2478 +       return 0; 
    2479 +} 
    2480 + 
    2481 +static int gsw_apply_config(struct switch_dev *dev) 
    2482 +{ 
    2483 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2484 +       int i; 
    2485 + 
    2486 +       for (i = 0; i < GSW_NUM_VLANS; i++) { 
    2487 +               gsw_set_vtcr(&gsw->swdev, i); 
    2488 +               if (gsw->global_vlan_enable) { 
    2489 +                       gsw_set_vlan_id(gsw, i, gsw->vlans[i].vid); 
    2490 +                       gsw_set_port_member(gsw, i, gsw->vlans[i].ports); 
    2491 +                       gsw_vlan_tagging_enable(gsw, i, 1); 
    2492 +               } else { 
    2493 +                       gsw_set_vlan_id(gsw, i, 0xfff); 
    2494 +                       gsw_set_port_member(gsw, i, 0); 
    2495 +                       gsw_vlan_tagging_enable(gsw, i, 0); 
    2496 +               } 
    2497 +               gsw_apply_vtcr(&gsw->swdev, i); 
    2498 +       } 
    2499 + 
    2500 +       for (i = 0; i < GSW_NUM_PORTS; i++) { 
    2501 +               if (gsw->global_vlan_enable) { 
    2502 +                       gsw_set_port_untag(gsw, i, !gsw->ports[i].untag); 
    2503 +                       gsw_set_pvid(gsw, i, gsw->ports[i].pvid); 
    2504 +               } else { 
    2505 +                       gsw_set_port_untag(gsw, i, 0); 
    2506 +                       gsw_set_pvid(gsw, i, 0); 
    2507 +               } 
    2508 +       } 
    2509 + 
    2510 +       if (!gsw->global_vlan_enable) 
    2511 +               gsw_set_vlan_id(gsw, 0, 0); 
    2512 + 
    2513 +       return 0; 
    2514 +} 
    2515 + 
    2516 +static int gsw_get_port_link(struct switch_dev *dev, 
    2517 +                        int port, 
    2518 +                        struct switch_port_link *link) 
    2519 +{ 
    2520 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2521 +       u32 status; 
    2522 + 
    2523 +       if (port < 0 || port >= GSW_NUM_PORTS) 
    2524 +               return -EINVAL; 
    2525 + 
    2526 +       status = gsw_r32(gsw, GSW_REG_PORT_STATUS(port)); 
    2527 +       link->link = status & 0x1; 
    2528 +       link->duplex = (status >> 1) & 1; 
    2529 + 
    2530 +       switch ((status >> 2) & 0x3) { 
    2531 +       case 0: 
    2532 +               link->speed = SWITCH_PORT_SPEED_10; 
    2533 +               break; 
    2534 +       case 1: 
    2535 +               link->speed = SWITCH_PORT_SPEED_100; 
    2536 +               break; 
    2537 +       case 2: 
    2538 +       case 3: // forced gige speed can be 2 or 3 
    2539 +               link->speed = SWITCH_PORT_SPEED_1000; 
    2540 +               break; 
    2541 +       } 
    2542 + 
    2543 +       return 0; 
    2544 +} 
    2545 + 
    2546 +static int gsw_set_port_bool(struct switch_dev *dev, 
    2547 +                        const struct switch_attr *attr, 
    2548 +                        struct switch_val *val) 
    2549 +{ 
    2550 +       struct mt7620_gsw *gsw = container_of(dev, struct mt7620_gsw, swdev); 
    2551 +       int idx = val->port_vlan; 
    2552 + 
    2553 +       if (idx < 0 || idx >= GSW_NUM_PORTS || 
    2554 +           val->value.i < 0 || val->value.i > 1) 
    2555 +               return -EINVAL; 
    2556 + 
    2557 +       switch (attr->id) { 
    2558 +       case GSW_ATTR_PORT_UNTAG: 
    2559 +               gsw->ports[idx].untag = val->value.i; 
    2560 +               break; 
    2561 +       default: 
    2562 +               return -EINVAL; 
    2563 +       } 
    2564 + 
    2565 +       return 0; 
    2566 +} 
    2567 + 
    2568 +static const struct switch_attr gsw_global[] = { 
    2569 +       { 
    2570 +               .type = SWITCH_TYPE_INT, 
    2571 +               .name = "enable_vlan", 
    2572 +               .description = "VLAN mode (1:enabled)", 
    2573 +               .max = 1, 
    2574 +               .id = GSW_ATTR_ENABLE_VLAN, 
    2575 +               .get = gsw_get_vlan_enable, 
    2576 +               .set = gsw_set_vlan_enable, 
    2577 +       }, 
    2578 +}; 
    2579 + 
    2580 +static const struct switch_attr gsw_port[] = { 
    2581 +       { 
    2582 +               .type = SWITCH_TYPE_INT, 
    2583 +               .name = "untag", 
    2584 +               .description = "Untag (1:strip outgoing vlan tag)", 
    2585 +               .max = 1, 
    2586 +               .id = GSW_ATTR_PORT_UNTAG, 
    2587 +               .get = gsw_get_port_bool, 
    2588 +               .set = gsw_set_port_bool, 
    2589 +       }, 
    2590 +}; 
    2591 + 
    2592 +static const struct switch_attr gsw_vlan[] = { 
    2593 +}; 
    2594 + 
    2595 +static const struct switch_dev_ops gsw_ops = { 
    2596 +       .attr_global = { 
    2597 +               .attr = gsw_global, 
    2598 +               .n_attr = ARRAY_SIZE(gsw_global), 
    2599 +       }, 
    2600 +       .attr_port = { 
    2601 +               .attr = gsw_port, 
    2602 +               .n_attr = ARRAY_SIZE(gsw_port), 
    2603 +       }, 
    2604 +       .attr_vlan = { 
    2605 +               .attr = gsw_vlan, 
    2606 +               .n_attr = ARRAY_SIZE(gsw_vlan), 
    2607 +       }, 
    2608 +       .get_vlan_ports = gsw_get_vlan_ports, 
    2609 +       .set_vlan_ports = gsw_set_vlan_ports, 
    2610 +       .get_port_pvid = gsw_get_port_pvid, 
    2611 +       .set_port_pvid = gsw_set_port_pvid, 
    2612 +       .get_port_link = gsw_get_port_link, 
    2613 +       .apply_config = gsw_apply_config, 
    2614 +       .reset_switch = gsw_reset_switch, 
    2615 +}; 
    2616 + 
    26172173+void mt7620_set_mac(struct fe_priv *priv, unsigned char *mac) 
    26182174+{ 
     
    26322188+}; 
    26332189+ 
     2190+int mt7620_gsw_config(struct fe_priv *priv) 
     2191+{ 
     2192+       struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv; 
     2193+ 
     2194+       /* is the mt7530 internal or external */ 
     2195+       if ((_mt7620_mii_read(gsw, 0x1f, 2) == 1) && (_mt7620_mii_read(gsw, 0x1f, 3) == 0xbeef)) 
     2196+               mt7530_probe(priv->device, NULL, priv->mii_bus); 
     2197+       else 
     2198+               mt7530_probe(priv->device, gsw->base, NULL); 
     2199+ 
     2200+       return 0; 
     2201+} 
     2202+ 
    26342203+int mt7620_gsw_probe(struct fe_priv *priv) 
    26352204+{ 
    26362205+       struct mt7620_gsw *gsw; 
    26372206+       struct device_node *np; 
    2638 +       struct switch_dev *swdev; 
    26392207+       const char *port4 = NULL; 
    26402208+ 
     
    26612229+       if (!gsw->base) { 
    26622230+               dev_err(priv->device, "gsw ioremap failed\n"); 
     2231+               return -ENOMEM; 
    26632232+       } 
    26642233+ 
    26652234+       gsw->dev = priv->device; 
    26662235+       priv->soc->swpriv = gsw; 
    2667 + 
    2668 +       swdev = &gsw->swdev; 
    2669 +       swdev->of_node = np; 
    2670 +       swdev->name = "mt7620a-gsw"; 
    2671 +       swdev->alias = "mt7620x"; 
    2672 +       swdev->cpu_port = GSW_PORT6; 
    2673 +       swdev->ports = GSW_NUM_PORTS; 
    2674 +       swdev->vlans = GSW_NUM_VLANS; 
    2675 +       swdev->ops = &gsw_ops; 
    2676 + 
    2677 +       if (register_switch(swdev, NULL)) 
    2678 +               dev_err(priv->device, "register_switch failed\n"); 
    26792236+ 
    26802237+       of_property_read_string(np, "ralink,port4", &port4); 
     
    26932250+       return 0; 
    26942251+} 
    2695 --- /dev/null 
    2696 +++ b/drivers/net/ethernet/ralink/gsw_mt7620a.h 
     2252Index: linux-3.10.13/drivers/net/ethernet/ralink/gsw_mt7620a.h 
     2253=================================================================== 
     2254--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     2255+++ linux-3.10.13/drivers/net/ethernet/ralink/gsw_mt7620a.h     2013-10-04 02:20:43.226145788 +0200 
     2256@@ -0,0 +1,30 @@ 
     2257+/* 
     2258+ *   This program is free software; you can redistribute it and/or modify 
     2259+ *   it under the terms of the GNU General Public License as published by 
     2260+ *   the Free Software Foundation; version 2 of the License 
     2261+ * 
     2262+ *   This program is distributed in the hope that it will be useful, 
     2263+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     2264+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     2265+ *   GNU General Public License for more details. 
     2266+ * 
     2267+ *   You should have received a copy of the GNU General Public License 
     2268+ *   along with this program; if not, write to the Free Software 
     2269+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     2270+ * 
     2271+ *   Copyright (C) 2009-2013 John Crispin <blogic@openwrt.org> 
     2272+ */ 
     2273+ 
     2274+#ifndef _RALINK_GSW_MT7620_H__ 
     2275+#define _RALINK_GSW_MT7620_H__ 
     2276+ 
     2277+extern int mt7620_gsw_config(struct fe_priv *priv); 
     2278+extern int mt7620_gsw_probe(struct fe_priv *priv); 
     2279+extern void mt7620_set_mac(struct fe_priv *priv, unsigned char *mac); 
     2280+extern int mt7620_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val); 
     2281+extern int mt7620_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg); 
     2282+extern void mt7620_mdio_link_adjust(struct fe_priv *priv, int port); 
     2283+extern void mt7620_port_init(struct fe_priv *priv, struct device_node *np); 
     2284+extern int mt7620a_has_carrier(struct fe_priv *priv); 
     2285+ 
     2286+#endif 
     2287Index: linux-3.10.13/drivers/net/ethernet/ralink/mdio.c 
     2288=================================================================== 
     2289--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     2290+++ linux-3.10.13/drivers/net/ethernet/ralink/mdio.c    2013-10-04 01:57:11.854085410 +0200 
     2291@@ -0,0 +1,244 @@ 
     2292+/* 
     2293+ *   This program is free software; you can redistribute it and/or modify 
     2294+ *   it under the terms of the GNU General Public License as published by 
     2295+ *   the Free Software Foundation; version 2 of the License 
     2296+ * 
     2297+ *   This program is distributed in the hope that it will be useful, 
     2298+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     2299+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     2300+ *   GNU General Public License for more details. 
     2301+ * 
     2302+ *   You should have received a copy of the GNU General Public License 
     2303+ *   along with this program; if not, write to the Free Software 
     2304+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     2305+ * 
     2306+ *   Copyright (C) 2009-2013 John Crispin <blogic@openwrt.org> 
     2307+ */ 
     2308+ 
     2309+#include <linux/module.h> 
     2310+#include <linux/kernel.h> 
     2311+#include <linux/types.h> 
     2312+#include <linux/dma-mapping.h> 
     2313+#include <linux/init.h> 
     2314+#include <linux/skbuff.h> 
     2315+#include <linux/etherdevice.h> 
     2316+#include <linux/ethtool.h> 
     2317+#include <linux/platform_device.h> 
     2318+#include <linux/phy.h> 
     2319+#include <linux/of_device.h> 
     2320+#include <linux/clk.h> 
     2321+#include <linux/of_net.h> 
     2322+#include <linux/of_mdio.h> 
     2323+ 
     2324+#include "ralink_soc_eth.h" 
     2325+#include "mdio.h" 
     2326+ 
     2327+static int fe_mdio_reset(struct mii_bus *bus) 
     2328+{ 
     2329+       /* TODO */ 
     2330+       return 0; 
     2331+} 
     2332+ 
     2333+static void fe_phy_link_adjust(struct net_device *dev) 
     2334+{ 
     2335+       struct fe_priv *priv = netdev_priv(dev); 
     2336+       unsigned long flags; 
     2337+       int i; 
     2338+ 
     2339+       spin_lock_irqsave(&priv->phy->lock, flags); 
     2340+       for (i = 0; i < 8; i++) { 
     2341+               if (priv->phy->phy_node[i]) { 
     2342+                       struct phy_device *phydev = priv->phy->phy[i]; 
     2343+                       int status_change = 0; 
     2344+ 
     2345+                       if (phydev->link) 
     2346+                               if (priv->phy->duplex[i] != phydev->duplex || 
     2347+                                               priv->phy->speed[i] != phydev->speed) 
     2348+                                       status_change = 1; 
     2349+ 
     2350+                       if (phydev->link != priv->link[i]) 
     2351+                               status_change = 1; 
     2352+ 
     2353+                       switch (phydev->speed) { 
     2354+                       case SPEED_1000: 
     2355+                       case SPEED_100: 
     2356+                       case SPEED_10: 
     2357+                               priv->link[i] = phydev->link; 
     2358+                               priv->phy->duplex[i] = phydev->duplex; 
     2359+                               priv->phy->speed[i] = phydev->speed; 
     2360+ 
     2361+                               if (status_change && priv->soc->mdio_adjust_link) 
     2362+                                       priv->soc->mdio_adjust_link(priv, i); 
     2363+                               break; 
     2364+                       } 
     2365+               } 
     2366+       } 
     2367+} 
     2368+ 
     2369+int fe_connect_phy_node(struct fe_priv *priv, struct device_node *phy_node) 
     2370+{ 
     2371+       const __be32 *_port = NULL; 
     2372+       struct phy_device *phydev; 
     2373+       int phy_mode, port; 
     2374+ 
     2375+       _port = of_get_property(phy_node, "reg", NULL); 
     2376+ 
     2377+       if (!_port || (be32_to_cpu(*_port) >= 0x20)) { 
     2378+               pr_err("%s: invalid port id\n", phy_node->name); 
     2379+               return -EINVAL; 
     2380+       } 
     2381+       port = be32_to_cpu(*_port); 
     2382+       phy_mode = of_get_phy_mode(phy_node); 
     2383+       if (phy_mode < 0) { 
     2384+               dev_err(priv->device, "incorrect phy-mode %d\n", phy_mode); 
     2385+               priv->phy->phy_node[port] = NULL; 
     2386+               return -EINVAL; 
     2387+       } 
     2388+ 
     2389+       phydev = of_phy_connect(priv->netdev, phy_node, fe_phy_link_adjust, 
     2390+                               0, phy_mode); 
     2391+       if (IS_ERR(phydev)) { 
     2392+               dev_err(priv->device, "could not connect to PHY\n"); 
     2393+               priv->phy->phy_node[port] = NULL; 
     2394+               return PTR_ERR(phydev); 
     2395+       } 
     2396+ 
     2397+       phydev->supported &= PHY_GBIT_FEATURES; 
     2398+       phydev->advertising = phydev->supported; 
     2399+       phydev->no_auto_carrier_off = 1; 
     2400+ 
     2401+       dev_info(priv->device, 
     2402+                "connected port %d to PHY at %s [uid=%08x, driver=%s]\n", 
     2403+                port, dev_name(&phydev->dev), phydev->phy_id, 
     2404+                phydev->drv->name); 
     2405+ 
     2406+       priv->phy->phy[port] = phydev; 
     2407+       priv->link[port] = 0; 
     2408+ 
     2409+       return 0; 
     2410+} 
     2411+ 
     2412+static int fe_phy_connect(struct fe_priv *priv) 
     2413+{ 
     2414+       return 0; 
     2415+} 
     2416+ 
     2417+static void fe_phy_disconnect(struct fe_priv *priv) 
     2418+{ 
     2419+       unsigned long flags; 
     2420+       int i; 
     2421+ 
     2422+       for (i = 0; i < 8; i++) 
     2423+               if (priv->phy->phy_fixed[i]) { 
     2424+                       spin_lock_irqsave(&priv->phy->lock, flags); 
     2425+                       priv->link[i] = 0; 
     2426+                       if (priv->soc->mdio_adjust_link) 
     2427+                               priv->soc->mdio_adjust_link(priv, i); 
     2428+                       spin_unlock_irqrestore(&priv->phy->lock, flags); 
     2429+               } else if (priv->phy->phy[i]) { 
     2430+                       phy_disconnect(priv->phy->phy[i]); 
     2431+               } 
     2432+} 
     2433+ 
     2434+static void fe_phy_start(struct fe_priv *priv) 
     2435+{ 
     2436+       unsigned long flags; 
     2437+       int i; 
     2438+ 
     2439+       for (i = 0; i < 8; i++) { 
     2440+               if (priv->phy->phy_fixed[i]) { 
     2441+                       spin_lock_irqsave(&priv->phy->lock, flags); 
     2442+                       priv->link[i] = 1; 
     2443+                       if (priv->soc->mdio_adjust_link) 
     2444+                               priv->soc->mdio_adjust_link(priv, i); 
     2445+                       spin_unlock_irqrestore(&priv->phy->lock, flags); 
     2446+               } else if (priv->phy->phy[i]) { 
     2447+                       phy_start(priv->phy->phy[i]); 
     2448+               } 
     2449+       } 
     2450+} 
     2451+ 
     2452+static void fe_phy_stop(struct fe_priv *priv) 
     2453+{ 
     2454+       unsigned long flags; 
     2455+       int i; 
     2456+ 
     2457+       for (i = 0; i < 8; i++) 
     2458+               if (priv->phy->phy_fixed[i]) { 
     2459+                       spin_lock_irqsave(&priv->phy->lock, flags); 
     2460+                       priv->link[i] = 0; 
     2461+                       if (priv->soc->mdio_adjust_link) 
     2462+                               priv->soc->mdio_adjust_link(priv, i); 
     2463+                       spin_unlock_irqrestore(&priv->phy->lock, flags); 
     2464+               } else if (priv->phy->phy[i]) { 
     2465+                       phy_stop(priv->phy->phy[i]); 
     2466+               } 
     2467+} 
     2468+ 
     2469+static struct fe_phy phy_ralink = { 
     2470+       .connect = fe_phy_connect, 
     2471+       .disconnect = fe_phy_disconnect, 
     2472+       .start = fe_phy_start, 
     2473+       .stop = fe_phy_stop, 
     2474+}; 
     2475+ 
     2476+int fe_mdio_init(struct fe_priv *priv) 
     2477+{ 
     2478+       struct device_node *mii_np; 
     2479+       int err; 
     2480+ 
     2481+       if (!priv->soc->mdio_read || !priv->soc->mdio_write) 
     2482+               return 0; 
     2483+ 
     2484+       spin_lock_init(&phy_ralink.lock); 
     2485+       priv->phy = &phy_ralink; 
     2486+ 
     2487+       mii_np = of_get_child_by_name(priv->device->of_node, "mdio-bus"); 
     2488+       if (!mii_np) { 
     2489+               dev_err(priv->device, "no %s child node found", "mdio-bus"); 
     2490+               return -ENODEV; 
     2491+       } 
     2492+ 
     2493+       if (!of_device_is_available(mii_np)) { 
     2494+               err = 0; 
     2495+               goto err_put_node; 
     2496+       } 
     2497+ 
     2498+       priv->mii_bus = mdiobus_alloc(); 
     2499+       if (priv->mii_bus == NULL) { 
     2500+               err = -ENOMEM; 
     2501+               goto err_put_node; 
     2502+       } 
     2503+ 
     2504+       priv->mii_bus->name = "mdio"; 
     2505+       priv->mii_bus->read = priv->soc->mdio_read; 
     2506+       priv->mii_bus->write = priv->soc->mdio_write; 
     2507+       priv->mii_bus->reset = fe_mdio_reset; 
     2508+       priv->mii_bus->irq = priv->mii_irq; 
     2509+       priv->mii_bus->priv = priv; 
     2510+       priv->mii_bus->parent = priv->device; 
     2511+ 
     2512+       snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name); 
     2513+       err = of_mdiobus_register(priv->mii_bus, mii_np); 
     2514+       if (err) 
     2515+               goto err_free_bus; 
     2516+ 
     2517+       return 0; 
     2518+ 
     2519+err_free_bus: 
     2520+       kfree(priv->mii_bus); 
     2521+err_put_node: 
     2522+       of_node_put(mii_np); 
     2523+       priv->mii_bus = NULL; 
     2524+       return err; 
     2525+} 
     2526+ 
     2527+void fe_mdio_cleanup(struct fe_priv *priv) 
     2528+{ 
     2529+       if (!priv->mii_bus) 
     2530+               return; 
     2531+ 
     2532+       mdiobus_unregister(priv->mii_bus); 
     2533+       of_node_put(priv->mii_bus->dev.of_node); 
     2534+       kfree(priv->mii_bus); 
     2535+} 
     2536Index: linux-3.10.13/drivers/net/ethernet/ralink/mdio.h 
     2537=================================================================== 
     2538--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     2539+++ linux-3.10.13/drivers/net/ethernet/ralink/mdio.h    2013-10-02 21:40:50.200369354 +0200 
    26972540@@ -0,0 +1,29 @@ 
    26982541+/* 
     
    27132556+ */ 
    27142557+ 
    2715 +#ifndef _RALINK_GSW_MT7620_H__ 
    2716 +#define _RALINK_GSW_MT7620_H__ 
    2717 + 
    2718 +extern int mt7620_gsw_probe(struct fe_priv *priv); 
    2719 +extern void mt7620_set_mac(struct fe_priv *priv, unsigned char *mac); 
    2720 +extern int mt7620_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val); 
    2721 +extern int mt7620_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg); 
    2722 +extern void mt7620_mdio_link_adjust(struct fe_priv *priv, int port); 
    2723 +extern void mt7620_port_init(struct fe_priv *priv, struct device_node *np); 
    2724 +extern int mt7620a_has_carrier(struct fe_priv *priv); 
    2725 + 
    2726 +#endif 
    2727 --- /dev/null 
    2728 +++ b/drivers/net/ethernet/ralink/mdio.c 
    2729 @@ -0,0 +1,245 @@ 
    2730 +/* 
    2731 + *   This program is free software; you can redistribute it and/or modify 
    2732 + *   it under the terms of the GNU General Public License as published by 
    2733 + *   the Free Software Foundation; version 2 of the License 
    2734 + * 
    2735 + *   This program is distributed in the hope that it will be useful, 
    2736 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
    2737 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    2738 + *   GNU General Public License for more details. 
    2739 + * 
    2740 + *   You should have received a copy of the GNU General Public License 
    2741 + *   along with this program; if not, write to the Free Software 
    2742 + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
    2743 + * 
    2744 + *   Copyright (C) 2009-2013 John Crispin <blogic@openwrt.org> 
    2745 + */ 
    2746 + 
    2747 +#include <linux/module.h> 
    2748 +#include <linux/kernel.h> 
    2749 +#include <linux/types.h> 
    2750 +#include <linux/dma-mapping.h> 
    2751 +#include <linux/init.h> 
    2752 +#include <linux/skbuff.h> 
    2753 +#include <linux/etherdevice.h> 
    2754 +#include <linux/ethtool.h> 
    2755 +#include <linux/platform_device.h> 
    2756 +#include <linux/phy.h> 
    2757 +#include <linux/of_device.h> 
    2758 +#include <linux/clk.h> 
    2759 +#include <linux/of_net.h> 
    2760 +#include <linux/of_mdio.h> 
    2761 + 
    2762 +#include "ralink_soc_eth.h" 
    2763 +#include "mdio.h" 
    2764 + 
    2765 +static int fe_mdio_reset(struct mii_bus *bus) 
    2766 +{ 
    2767 +       /* TODO */ 
    2768 +       return 0; 
    2769 +} 
    2770 + 
    2771 +static void fe_phy_link_adjust(struct net_device *dev) 
    2772 +{ 
    2773 +       struct fe_priv *priv = netdev_priv(dev); 
    2774 +       unsigned long flags; 
    2775 +       int i; 
    2776 + 
    2777 +       spin_lock_irqsave(&priv->phy->lock, flags); 
    2778 +       for (i = 0; i < 8; i++) { 
    2779 +               if (priv->phy->phy_node[i]) { 
    2780 +                       struct phy_device *phydev = priv->phy->phy[i]; 
    2781 +                       int status_change = 0; 
    2782 + 
    2783 +                       if (phydev->link) 
    2784 +                               if (priv->phy->duplex[i] != phydev->duplex || 
    2785 +                                               priv->phy->speed[i] != phydev->speed) 
    2786 +                                       status_change = 1; 
    2787 + 
    2788 +                       if (phydev->link != priv->link[i]) 
    2789 +                               status_change = 1; 
    2790 + 
    2791 +                       switch (phydev->speed) { 
    2792 +                       case SPEED_1000: 
    2793 +                       case SPEED_100: 
    2794 +                       case SPEED_10: 
    2795 +                               priv->link[i] = phydev->link; 
    2796 +                               priv->phy->duplex[i] = phydev->duplex; 
    2797 +                               priv->phy->speed[i] = phydev->speed; 
    2798 + 
    2799 +                               if (status_change && priv->soc->mdio_adjust_link) 
    2800 +                                       priv->soc->mdio_adjust_link(priv, i); 
    2801 +                               break; 
    2802 +                       } 
    2803 +               } 
    2804 +       } 
    2805 +       spin_unlock_irqrestore(&priv->phy->lock, flags); 
    2806 +} 
    2807 + 
    2808 +int fe_connect_phy_node(struct fe_priv *priv, struct device_node *phy_node) 
    2809 +{ 
    2810 +       const __be32 *_port = NULL; 
    2811 +       struct phy_device *phydev; 
    2812 +       int phy_mode, port; 
    2813 + 
    2814 +       _port = of_get_property(phy_node, "reg", NULL); 
    2815 + 
    2816 +       if (!_port || (be32_to_cpu(*_port) >= 8)) { 
    2817 +               pr_err("%s: invalid port id\n", phy_node->name); 
    2818 +               return -EINVAL; 
    2819 +       } 
    2820 +       port = be32_to_cpu(*_port); 
    2821 +       phy_mode = of_get_phy_mode(phy_node); 
    2822 +       if (phy_mode < 0) { 
    2823 +               dev_err(priv->device, "incorrect phy-mode %d\n", phy_mode); 
    2824 +               priv->phy->phy_node[port] = NULL; 
    2825 +               return -EINVAL; 
    2826 +       } 
    2827 + 
    2828 +       phydev = of_phy_connect(priv->netdev, phy_node, fe_phy_link_adjust, 
    2829 +                               0, phy_mode); 
    2830 +       if (IS_ERR(phydev)) { 
    2831 +               dev_err(priv->device, "could not connect to PHY\n"); 
    2832 +               priv->phy->phy_node[port] = NULL; 
    2833 +               return PTR_ERR(phydev); 
    2834 +       } 
    2835 + 
    2836 +       phydev->supported &= PHY_GBIT_FEATURES; 
    2837 +       phydev->advertising = phydev->supported; 
    2838 +       phydev->no_auto_carrier_off = 1; 
    2839 + 
    2840 +       dev_info(priv->device, 
    2841 +                "connected port %d to PHY at %s [uid=%08x, driver=%s]\n", 
    2842 +                port, dev_name(&phydev->dev), phydev->phy_id, 
    2843 +                phydev->drv->name); 
    2844 + 
    2845 +       priv->phy->phy[port] = phydev; 
    2846 +       priv->link[port] = 0; 
    2847 + 
    2848 +       return 0; 
    2849 +} 
    2850 + 
    2851 +static int fe_phy_connect(struct fe_priv *priv) 
    2852 +{ 
    2853 +       return 0; 
    2854 +} 
    2855 + 
    2856 +static void fe_phy_disconnect(struct fe_priv *priv) 
    2857 +{ 
    2858 +       unsigned long flags; 
    2859 +       int i; 
    2860 + 
    2861 +       for (i = 0; i < 8; i++) 
    2862 +               if (priv->phy->phy_fixed[i]) { 
    2863 +                       spin_lock_irqsave(&priv->phy->lock, flags); 
    2864 +                       priv->link[i] = 0; 
    2865 +                       if (priv->soc->mdio_adjust_link) 
    2866 +                               priv->soc->mdio_adjust_link(priv, i); 
    2867 +                       spin_unlock_irqrestore(&priv->phy->lock, flags); 
    2868 +               } else if (priv->phy->phy[i]) { 
    2869 +                       phy_disconnect(priv->phy->phy[i]); 
    2870 +               } 
    2871 +} 
    2872 + 
    2873 +static void fe_phy_start(struct fe_priv *priv) 
    2874 +{ 
    2875 +       unsigned long flags; 
    2876 +       int i; 
    2877 + 
    2878 +       for (i = 0; i < 8; i++) { 
    2879 +               if (priv->phy->phy_fixed[i]) { 
    2880 +                       spin_lock_irqsave(&priv->phy->lock, flags); 
    2881 +                       priv->link[i] = 1; 
    2882 +                       if (priv->soc->mdio_adjust_link) 
    2883 +                               priv->soc->mdio_adjust_link(priv, i); 
    2884 +                       spin_unlock_irqrestore(&priv->phy->lock, flags); 
    2885 +               } else if (priv->phy->phy[i]) { 
    2886 +                       phy_start(priv->phy->phy[i]); 
    2887 +               } 
    2888 +       } 
    2889 +} 
    2890 + 
    2891 +static void fe_phy_stop(struct fe_priv *priv) 
    2892 +{ 
    2893 +       unsigned long flags; 
    2894 +       int i; 
    2895 + 
    2896 +       for (i = 0; i < 8; i++) 
    2897 +               if (priv->phy->phy_fixed[i]) { 
    2898 +                       spin_lock_irqsave(&priv->phy->lock, flags); 
    2899 +                       priv->link[i] = 0; 
    2900 +                       if (priv->soc->mdio_adjust_link) 
    2901 +                               priv->soc->mdio_adjust_link(priv, i); 
    2902 +                       spin_unlock_irqrestore(&priv->phy->lock, flags); 
    2903 +               } else if (priv->phy->phy[i]) { 
    2904 +                       phy_stop(priv->phy->phy[i]); 
    2905 +               } 
    2906 +} 
    2907 + 
    2908 +static struct fe_phy phy_ralink = { 
    2909 +       .connect = fe_phy_connect, 
    2910 +       .disconnect = fe_phy_disconnect, 
    2911 +       .start = fe_phy_start, 
    2912 +       .stop = fe_phy_stop, 
    2913 +}; 
    2914 + 
    2915 +int fe_mdio_init(struct fe_priv *priv) 
    2916 +{ 
    2917 +       struct device_node *mii_np; 
    2918 +       int err; 
    2919 + 
    2920 +       if (!priv->soc->mdio_read || !priv->soc->mdio_write) 
    2921 +               return 0; 
    2922 + 
    2923 +       spin_lock_init(&phy_ralink.lock); 
    2924 +       priv->phy = &phy_ralink; 
    2925 + 
    2926 +       mii_np = of_get_child_by_name(priv->device->of_node, "mdio-bus"); 
    2927 +       if (!mii_np) { 
    2928 +               dev_err(priv->device, "no %s child node found", "mdio-bus"); 
    2929 +               return -ENODEV; 
    2930 +       } 
    2931 + 
    2932 +       if (!of_device_is_available(mii_np)) { 
    2933 +               err = 0; 
    2934 +               goto err_put_node; 
    2935 +       } 
    2936 + 
    2937 +       priv->mii_bus = mdiobus_alloc(); 
    2938 +       if (priv->mii_bus == NULL) { 
    2939 +               err = -ENOMEM; 
    2940 +               goto err_put_node; 
    2941 +       } 
    2942 + 
    2943 +       priv->mii_bus->name = "mdio"; 
    2944 +       priv->mii_bus->read = priv->soc->mdio_read; 
    2945 +       priv->mii_bus->write = priv->soc->mdio_write; 
    2946 +       priv->mii_bus->reset = fe_mdio_reset; 
    2947 +       priv->mii_bus->irq = priv->mii_irq; 
    2948 +       priv->mii_bus->priv = priv; 
    2949 +       priv->mii_bus->parent = priv->device; 
    2950 + 
    2951 +       snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name); 
    2952 +       err = of_mdiobus_register(priv->mii_bus, mii_np); 
    2953 +       if (err) 
    2954 +               goto err_free_bus; 
    2955 + 
    2956 +       return 0; 
    2957 + 
    2958 +err_free_bus: 
    2959 +       kfree(priv->mii_bus); 
    2960 +err_put_node: 
    2961 +       of_node_put(mii_np); 
    2962 +       priv->mii_bus = NULL; 
    2963 +       return err; 
    2964 +} 
    2965 + 
    2966 +void fe_mdio_cleanup(struct fe_priv *priv) 
    2967 +{ 
    2968 +       if (!priv->mii_bus) 
    2969 +               return; 
    2970 + 
    2971 +       mdiobus_unregister(priv->mii_bus); 
    2972 +       of_node_put(priv->mii_bus->dev.of_node); 
    2973 +       kfree(priv->mii_bus); 
    2974 +} 
    2975 --- /dev/null 
    2976 +++ b/drivers/net/ethernet/ralink/mdio.h 
    2977 @@ -0,0 +1,29 @@ 
    2978 +/* 
    2979 + *   This program is free software; you can redistribute it and/or modify 
    2980 + *   it under the terms of the GNU General Public License as published by 
    2981 + *   the Free Software Foundation; version 2 of the License 
    2982 + * 
    2983 + *   This program is distributed in the hope that it will be useful, 
    2984 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
    2985 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    2986 + *   GNU General Public License for more details. 
    2987 + * 
    2988 + *   You should have received a copy of the GNU General Public License 
    2989 + *   along with this program; if not, write to the Free Software 
    2990 + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
    2991 + * 
    2992 + *   Copyright (C) 2009-2013 John Crispin <blogic@openwrt.org> 
    2993 + */ 
    2994 + 
    29952558+#ifndef _RALINK_MDIO_H__ 
    29962559+#define _RALINK_MDIO_H__ 
     
    30052568+#endif 
    30062569+#endif 
    3007 --- /dev/null 
    3008 +++ b/drivers/net/ethernet/ralink/mdio_rt2880.c 
     2570Index: linux-3.10.13/drivers/net/ethernet/ralink/mdio_rt2880.c 
     2571=================================================================== 
     2572--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     2573+++ linux-3.10.13/drivers/net/ethernet/ralink/mdio_rt2880.c     2013-10-02 21:40:50.200369354 +0200 
    30092574@@ -0,0 +1,232 @@ 
    30102575+/* 
     
    32402805+       return; 
    32412806+} 
    3242 --- /dev/null 
    3243 +++ b/drivers/net/ethernet/ralink/mdio_rt2880.h 
     2807Index: linux-3.10.13/drivers/net/ethernet/ralink/mdio_rt2880.h 
     2808=================================================================== 
     2809--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     2810+++ linux-3.10.13/drivers/net/ethernet/ralink/mdio_rt2880.h     2013-10-02 21:40:50.204369354 +0200 
    32442811@@ -0,0 +1,26 @@ 
    32452812+/* 
     
    32692836+ 
    32702837+#endif 
    3271 --- /dev/null 
    3272 +++ b/drivers/net/ethernet/ralink/ralink_soc_eth.c 
    3273 @@ -0,0 +1,735 @@ 
     2838Index: linux-3.10.13/drivers/net/ethernet/ralink/ralink_soc_eth.c 
     2839=================================================================== 
     2840--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     2841+++ linux-3.10.13/drivers/net/ethernet/ralink/ralink_soc_eth.c  2013-10-04 02:18:27.242139979 +0200 
     2842@@ -0,0 +1,738 @@ 
    32742843+/* 
    32752844+ *   This program is free software; you can redistribute it and/or modify 
     
    38453414+       if (priv->soc->port_init) 
    38463415+               for_each_child_of_node(priv->device->of_node, port) 
    3847 +                       if (of_device_is_compatible(port, "ralink,eth-port")) 
     3416+                       if (of_device_is_compatible(port, "ralink,eth-port") && of_device_is_available(port)) 
    38483417+                               priv->soc->port_init(priv, port); 
    38493418+ 
     
    38513420+       if (err) 
    38523421+               goto err_phy_disconnect; 
     3422+ 
     3423+       if (priv->soc->switch_config) 
     3424+               priv->soc->switch_config(priv); 
    38533425+ 
    38543426+       return 0; 
     
    40073579+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); 
    40083580+MODULE_DESCRIPTION("Ethernet driver for Ralink SoC"); 
    4009 --- /dev/null 
    4010 +++ b/drivers/net/ethernet/ralink/ralink_soc_eth.h 
    4011 @@ -0,0 +1,374 @@ 
     3581Index: linux-3.10.13/drivers/net/ethernet/ralink/ralink_soc_eth.h 
     3582=================================================================== 
     3583--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     3584+++ linux-3.10.13/drivers/net/ethernet/ralink/ralink_soc_eth.h  2013-10-04 02:18:45.454140650 +0200 
     3585@@ -0,0 +1,375 @@ 
    40123586+/* 
    40133587+ *   This program is free software; you can redistribute it and/or modify 
     
    43343908+       void (*rx_dma)(struct fe_priv *priv, int idx, int len); 
    43353909+       int (*switch_init)(struct fe_priv *priv); 
     3910+       int (*switch_config)(struct fe_priv *priv); 
    43363911+       void (*port_init)(struct fe_priv *priv, struct device_node *port); 
    43373912+       int (*has_carrier)(struct fe_priv *priv); 
     
    43843959+ 
    43853960+#endif /* FE_ETH_H */ 
    4386 --- /dev/null 
    4387 +++ b/drivers/net/ethernet/ralink/soc_mt7620.c 
    4388 @@ -0,0 +1,111 @@ 
     3961Index: linux-3.10.13/drivers/net/ethernet/ralink/soc_mt7620.c 
     3962=================================================================== 
     3963--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     3964+++ linux-3.10.13/drivers/net/ethernet/ralink/soc_mt7620.c      2013-10-04 02:21:02.450146612 +0200 
     3965@@ -0,0 +1,112 @@ 
    43893966+/* 
    43903967+ *   This program is free software; you can redistribute it and/or modify 
     
    44794056+       .rx_dma = mt7620_rx_dma, 
    44804057+       .switch_init = mt7620_gsw_probe, 
     4058+       .switch_config = mt7620_gsw_config, 
    44814059+       .port_init = mt7620_port_init, 
    44824060+       .min_pkt_len = 0, 
     
    44984076+ 
    44994077+MODULE_DEVICE_TABLE(of, of_fe_match); 
    4500 --- /dev/null 
    4501 +++ b/drivers/net/ethernet/ralink/soc_rt2880.c 
     4078Index: linux-3.10.13/drivers/net/ethernet/ralink/soc_rt2880.c 
     4079=================================================================== 
     4080--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     4081+++ linux-3.10.13/drivers/net/ethernet/ralink/soc_rt2880.c      2013-10-02 21:40:50.204369354 +0200 
    45024082@@ -0,0 +1,51 @@ 
    45034083+/* 
     
    45524132+ 
    45534133+MODULE_DEVICE_TABLE(of, of_fe_match); 
    4554 --- /dev/null 
    4555 +++ b/drivers/net/ethernet/ralink/soc_rt305x.c 
     4134Index: linux-3.10.13/drivers/net/ethernet/ralink/soc_rt305x.c 
     4135=================================================================== 
     4136--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     4137+++ linux-3.10.13/drivers/net/ethernet/ralink/soc_rt305x.c      2013-10-02 21:40:50.208369356 +0200 
    45564138@@ -0,0 +1,113 @@ 
    45574139+/* 
     
    46684250+ 
    46694251+MODULE_DEVICE_TABLE(of, of_fe_match); 
    4670 --- /dev/null 
    4671 +++ b/drivers/net/ethernet/ralink/soc_rt3883.c 
     4252Index: linux-3.10.13/drivers/net/ethernet/ralink/soc_rt3883.c 
     4253=================================================================== 
     4254--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     4255+++ linux-3.10.13/drivers/net/ethernet/ralink/soc_rt3883.c      2013-10-02 21:40:50.208369356 +0200 
    46724256@@ -0,0 +1,60 @@ 
    46734257+/* 
     
    47314315+MODULE_DEVICE_TABLE(of, of_fe_match); 
    47324316+ 
     4317Index: linux-3.10.13/drivers/net/ethernet/ralink/mt7530.c 
     4318=================================================================== 
     4319--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     4320+++ linux-3.10.13/drivers/net/ethernet/ralink/mt7530.c  2013-10-04 19:37:31.585208659 +0200 
     4321@@ -0,0 +1,462 @@ 
     4322+/* 
     4323+ * This program is free software; you can redistribute it and/or 
     4324+ * modify it under the terms of the GNU General Public License 
     4325+ * as published by the Free Software Foundation; either version 2 
     4326+ * of the License, or (at your option) any later version. 
     4327+ * 
     4328+ * This program is distributed in the hope that it will be useful, 
     4329+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     4330+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     4331+ * GNU General Public License for more details. 
     4332+ * 
     4333+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org> 
     4334+ */ 
     4335+ 
     4336+#include <linux/if.h> 
     4337+#include <linux/module.h> 
     4338+#include <linux/init.h> 
     4339+#include <linux/list.h> 
     4340+#include <linux/if_ether.h> 
     4341+#include <linux/skbuff.h> 
     4342+#include <linux/netdevice.h> 
     4343+#include <linux/netlink.h> 
     4344+#include <linux/bitops.h> 
     4345+#include <net/genetlink.h> 
     4346+#include <linux/switch.h> 
     4347+#include <linux/delay.h> 
     4348+#include <linux/phy.h> 
     4349+#include <linux/netdevice.h> 
     4350+#include <linux/etherdevice.h> 
     4351+#include <linux/lockdep.h> 
     4352+#include <linux/workqueue.h> 
     4353+#include <linux/of_device.h> 
     4354+ 
     4355+#include "mt7530.h" 
     4356+ 
     4357+#define MT7530_CPU_PORT                6 
     4358+#define MT7530_NUM_PORTS       7 
     4359+#define MT7530_NUM_VLANS       16 
     4360+#define MT7530_NUM_VIDS                16 
     4361+ 
     4362+#define REG_ESW_VLAN_VTCR      0x90 
     4363+#define REG_ESW_VLAN_VAWD1     0x94 
     4364+#define REG_ESW_VLAN_VAWD2     0x98 
     4365+ 
     4366+enum { 
     4367+       /* Global attributes. */ 
     4368+       MT7530_ATTR_ENABLE_VLAN, 
     4369+}; 
     4370+ 
     4371+struct mt7530_port { 
     4372+       u16     pvid; 
     4373+}; 
     4374+ 
     4375+struct mt7530_vlan { 
     4376+       u8      ports; 
     4377+}; 
     4378+ 
     4379+struct mt7530_priv { 
     4380+       void __iomem            *base; 
     4381+       struct mii_bus          *bus; 
     4382+       struct switch_dev       swdev; 
     4383+ 
     4384+       bool                    global_vlan_enable; 
     4385+       struct mt7530_vlan      vlans[MT7530_NUM_VLANS]; 
     4386+       struct mt7530_port      ports[MT7530_NUM_PORTS]; 
     4387+}; 
     4388+ 
     4389+struct mt7530_mapping { 
     4390+       char    *name; 
     4391+       u8      pvids[6]; 
     4392+       u8      vlans[8]; 
     4393+} mt7530_defaults[] = { 
     4394+       { 
     4395+               .name = "llllw", 
     4396+               .pvids = { 1, 1, 1, 1, 2, 1 }, 
     4397+               .vlans = { 0, 0x4f, 0x50 }, 
     4398+       }, { 
     4399+               .name = "wllll", 
     4400+               .pvids = { 2, 1, 1, 1, 1, 1 }, 
     4401+               .vlans = { 0, 0x5e, 0x41 }, 
     4402+       }, 
     4403+}; 
     4404+ 
     4405+struct mt7530_mapping* 
     4406+mt7530_find_mapping(struct device_node *np) 
     4407+{ 
     4408+       const char *map; 
     4409+       int i; 
     4410+ 
     4411+       if (of_property_read_string(np, "ralink,port-map", &map)) 
     4412+               return NULL; 
     4413+ 
     4414+       for (i = 0; i < ARRAY_SIZE(mt7530_defaults); i++) 
     4415+               if (!strcmp(map, mt7530_defaults[i].name)) 
     4416+                       return &mt7530_defaults[i]; 
     4417+ 
     4418+       return NULL; 
     4419+} 
     4420+ 
     4421+static void 
     4422+mt7530_apply_mapping(struct mt7530_priv *mt7530, struct mt7530_mapping *map) 
     4423+{ 
     4424+       int i = 0; 
     4425+ 
     4426+       mt7530->global_vlan_enable = 1; 
     4427+ 
     4428+       for (i = 0; i < 6; i++) 
     4429+               mt7530->ports[i].pvid = map->pvids[i]; 
     4430+       for (i = 0; i < 8; i++) 
     4431+               mt7530->vlans[i].ports = map->vlans[i]; 
     4432+} 
     4433+ 
     4434+static int 
     4435+mt7530_reset_switch(struct switch_dev *dev) 
     4436+{ 
     4437+       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); 
     4438+ 
     4439+       memset(priv->ports, 0, sizeof(priv->ports)); 
     4440+       memset(priv->vlans, 0, sizeof(priv->vlans)); 
     4441+ 
     4442+       return 0; 
     4443+} 
     4444+ 
     4445+static int 
     4446+mt7530_get_vlan_enable(struct switch_dev *dev, 
     4447+                          const struct switch_attr *attr, 
     4448+                          struct switch_val *val) 
     4449+{ 
     4450+       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); 
     4451+ 
     4452+       val->value.i = priv->global_vlan_enable; 
     4453+ 
     4454+       return 0; 
     4455+} 
     4456+ 
     4457+static int 
     4458+mt7530_set_vlan_enable(struct switch_dev *dev, 
     4459+                          const struct switch_attr *attr, 
     4460+                          struct switch_val *val) 
     4461+{ 
     4462+       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); 
     4463+ 
     4464+       priv->global_vlan_enable = val->value.i != 0; 
     4465+ 
     4466+       return 0; 
     4467+} 
     4468+ 
     4469+static u32 
     4470+mt7530_r32(struct mt7530_priv *priv, u32 reg) 
     4471+{ 
     4472+       if (priv->bus) { 
     4473+               u16 high, low; 
     4474+ 
     4475+               mdiobus_write(priv->bus, 0x1f, 0x1f, (reg >> 6) & 0x3ff); 
     4476+               low = mdiobus_read(priv->bus, 0x1f, (reg >> 2) & 0xf); 
     4477+               high = mdiobus_read(priv->bus, 0x1f, 0x10); 
     4478+ 
     4479+               return (high << 16) | (low & 0xffff); 
     4480+       } 
     4481+ 
     4482+        return ioread32(priv->base + reg); 
     4483+} 
     4484+ 
     4485+static void 
     4486+mt7530_w32(struct mt7530_priv *priv, u32 reg, u32 val) 
     4487+{ 
     4488+       if (priv->bus) { 
     4489+               mdiobus_write(priv->bus, 0x1f, 0x1f, (reg >> 6) & 0x3ff); 
     4490+               mdiobus_write(priv->bus, 0x1f, (reg >> 2) & 0xf,  val & 0xffff); 
     4491+               mdiobus_write(priv->bus, 0x1f, 0x10, val >> 16); 
     4492+               return; 
     4493+       } 
     4494+ 
     4495+       iowrite32(val, priv->base + reg); 
     4496+} 
     4497+ 
     4498+static void 
     4499+mt7530_vtcr(struct mt7530_priv *priv, u32 cmd, u32 val) 
     4500+{ 
     4501+       int i; 
     4502+ 
     4503+       mt7530_w32(priv, REG_ESW_VLAN_VTCR, BIT(31) | (cmd << 12) | val); 
     4504+ 
     4505+       for (i = 0; i < 20; i++) { 
     4506+               u32 val = mt7530_r32(priv, REG_ESW_VLAN_VTCR); 
     4507+ 
     4508+               if ((val & BIT(31)) == 0) 
     4509+                       break; 
     4510+ 
     4511+               udelay(1000); 
     4512+       } 
     4513+       if (i == 20) 
     4514+               printk("mt7530: vtcr timeout\n"); 
     4515+} 
     4516+ 
     4517+static int 
     4518+mt7530_get_port_pvid(struct switch_dev *dev, int port, int *val) 
     4519+{ 
     4520+       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); 
     4521+ 
     4522+       if (port >= MT7530_NUM_PORTS) 
     4523+               return -EINVAL; 
     4524+ 
     4525+       *val = mt7530_r32(priv, 0x2014 + (0x100 * port)); 
     4526+       *val &= 0xff; 
     4527+ 
     4528+       return 0; 
     4529+} 
     4530+ 
     4531+static int 
     4532+mt7530_set_port_pvid(struct switch_dev *dev, int port, int pvid) 
     4533+{ 
     4534+       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); 
     4535+ 
     4536+       if (port >= MT7530_NUM_PORTS) 
     4537+               return -1; 
     4538+ 
     4539+       priv->ports[port].pvid = pvid; 
     4540+ 
     4541+       return 0; 
     4542+} 
     4543+ 
     4544+static int 
     4545+mt7530_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) 
     4546+{ 
     4547+       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); 
     4548+       u32 member; 
     4549+       int i; 
     4550+ 
     4551+       val->len = 0; 
     4552+ 
     4553+       if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VIDS) 
     4554+               return -EINVAL; 
     4555+ 
     4556+       mt7530_vtcr(priv, 0, val->port_vlan); 
     4557+       member = mt7530_r32(priv, REG_ESW_VLAN_VAWD1); 
     4558+       member >>= 16; 
     4559+       member &= 0xff; 
     4560+ 
     4561+       for (i = 0; i < MT7530_NUM_PORTS; i++) { 
     4562+               struct switch_port *p; 
     4563+               if (!(member & BIT(i))) 
     4564+                       continue; 
     4565+ 
     4566+               p = &val->value.ports[val->len++]; 
     4567+               p->id = i; 
     4568+               p->flags = 0; 
     4569+       } 
     4570+ 
     4571+       return 0; 
     4572+} 
     4573+ 
     4574+static int 
     4575+mt7530_set_vlan_ports(struct switch_dev *dev, struct switch_val *val) 
     4576+{ 
     4577+       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); 
     4578+       int ports = 0; 
     4579+       int i; 
     4580+ 
     4581+       if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VIDS || 
     4582+                       val->len > MT7530_NUM_PORTS) 
     4583+               return -EINVAL; 
     4584+ 
     4585+       for (i = 0; i < val->len; i++) { 
     4586+               struct switch_port *p = &val->value.ports[i]; 
     4587+ 
     4588+               if (p->id >= MT7530_NUM_PORTS) 
     4589+                       return -EINVAL; 
     4590+ 
     4591+               ports |= BIT(p->id); 
     4592+       } 
     4593+       priv->vlans[val->port_vlan].ports = ports; 
     4594+ 
     4595+       return 0; 
     4596+} 
     4597+ 
     4598+static int 
     4599+mt7530_apply_config(struct switch_dev *dev) 
     4600+{ 
     4601+       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); 
     4602+       int i; 
     4603+ 
     4604+       if (!priv->global_vlan_enable) { 
     4605+               mt7530_w32(priv, 0x2004, 0xff000); 
     4606+               mt7530_w32(priv, 0x2104, 0xff000); 
     4607+               mt7530_w32(priv, 0x2204, 0xff000); 
     4608+               mt7530_w32(priv, 0x2304, 0xff000); 
     4609+               mt7530_w32(priv, 0x2404, 0xff000); 
     4610+               mt7530_w32(priv, 0x2504, 0xff000); 
     4611+               mt7530_w32(priv, 0x2604, 0xff000); 
     4612+               mt7530_w32(priv, 0x2010, 0x810000c); 
     4613+               mt7530_w32(priv, 0x2110, 0x810000c); 
     4614+               mt7530_w32(priv, 0x2210, 0x810000c); 
     4615+               mt7530_w32(priv, 0x2310, 0x810000c); 
     4616+               mt7530_w32(priv, 0x2410, 0x810000c); 
     4617+               mt7530_w32(priv, 0x2510, 0x810000c); 
     4618+               mt7530_w32(priv, 0x2610, 0x810000c); 
     4619+               return 0; 
     4620+       } 
     4621+ 
     4622+       // LAN/WAN ports as security mode 
     4623+       mt7530_w32(priv, 0x2004, 0xff0003); 
     4624+       mt7530_w32(priv, 0x2104, 0xff0003); 
     4625+       mt7530_w32(priv, 0x2204, 0xff0003); 
     4626+       mt7530_w32(priv, 0x2304, 0xff0003); 
     4627+       mt7530_w32(priv, 0x2404, 0xff0003); 
     4628+       mt7530_w32(priv, 0x2504, 0xff0003); 
     4629+       // LAN/WAN ports as transparent port 
     4630+       mt7530_w32(priv, 0x2010, 0x810000c0); 
     4631+       mt7530_w32(priv, 0x2110, 0x810000c0); 
     4632+       mt7530_w32(priv, 0x2210, 0x810000c0); 
     4633+       mt7530_w32(priv, 0x2310, 0x810000c0); 
     4634+       mt7530_w32(priv, 0x2410, 0x810000c0); 
     4635+       mt7530_w32(priv, 0x2510, 0x810000c0); 
     4636+       // set CPU/P7 port as user port 
     4637+       mt7530_w32(priv, 0x2610, 0x81000000); 
     4638+       mt7530_w32(priv, 0x2710, 0x81000000); 
     4639+ 
     4640+       mt7530_w32(priv, 0x2604, 0x20ff0003); 
     4641+       mt7530_w32(priv, 0x2704, 0x20ff0003); 
     4642+       mt7530_w32(priv, 0x2610, 0x81000000); 
     4643+ 
     4644+       for (i = 0; i < MT7530_NUM_VLANS; i++) { 
     4645+               u8 ports = priv->vlans[i].ports; 
     4646+ 
     4647+               if (ports) 
     4648+                       mt7530_w32(priv, REG_ESW_VLAN_VAWD1, BIT(30) | (ports << 16) | BIT(0)); 
     4649+               else 
     4650+                       mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0); 
     4651+ 
     4652+               mt7530_vtcr(priv, 1, i); 
     4653+       } 
     4654+ 
     4655+       for (i = 0; i < MT7530_NUM_PORTS; i++) 
     4656+               mt7530_w32(priv, 0x2014 + (0x100 * i), 0x10000 | priv->ports[i].pvid); 
     4657+ 
     4658+       return 0; 
     4659+} 
     4660+ 
     4661+static int 
     4662+mt7530_get_port_link(struct switch_dev *dev,  int port, 
     4663+                        struct switch_port_link *link) 
     4664+{ 
     4665+       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); 
     4666+       u32 speed, pmsr; 
     4667+ 
     4668+       if (port < 0 || port >= MT7530_NUM_PORTS) 
     4669+               return -EINVAL; 
     4670+ 
     4671+       pmsr = mt7530_r32(priv, 0x3008 + (0x100 * port)); 
     4672+ 
     4673+       link->link = pmsr & 1; 
     4674+       link->duplex = (pmsr >> 1) & 1; 
     4675+       speed = (pmsr >> 2) & 3; 
     4676+ 
     4677+       switch (speed) { 
     4678+       case 0: 
     4679+               link->speed = SWITCH_PORT_SPEED_10; 
     4680+               break; 
     4681+       case 1: 
     4682+               link->speed = SWITCH_PORT_SPEED_100; 
     4683+               break; 
     4684+       case 2: 
     4685+       case 3: /* forced gige speed can be 2 or 3 */ 
     4686+               link->speed = SWITCH_PORT_SPEED_1000; 
     4687+               break; 
     4688+       default: 
     4689+               link->speed = SWITCH_PORT_SPEED_UNKNOWN; 
     4690+               break; 
     4691+       } 
     4692+ 
     4693+       return 0; 
     4694+} 
     4695+ 
     4696+static const struct switch_attr mt7530_global[] = { 
     4697+       { 
     4698+               .type = SWITCH_TYPE_INT, 
     4699+               .name = "enable_vlan", 
     4700+               .description = "VLAN mode (1:enabled)", 
     4701+               .max = 1, 
     4702+               .id = MT7530_ATTR_ENABLE_VLAN, 
     4703+               .get = mt7530_get_vlan_enable, 
     4704+               .set = mt7530_set_vlan_enable, 
     4705+       }, 
     4706+}; 
     4707+ 
     4708+static const struct switch_attr mt7530_port[] = { 
     4709+}; 
     4710+ 
     4711+static const struct switch_attr mt7530_vlan[] = { 
     4712+}; 
     4713+ 
     4714+static const struct switch_dev_ops mt7530_ops = { 
     4715+       .attr_global = { 
     4716+               .attr = mt7530_global, 
     4717+               .n_attr = ARRAY_SIZE(mt7530_global), 
     4718+       }, 
     4719+       .attr_port = { 
     4720+               .attr = mt7530_port, 
     4721+               .n_attr = ARRAY_SIZE(mt7530_port), 
     4722+       }, 
     4723+       .attr_vlan = { 
     4724+               .attr = mt7530_vlan, 
     4725+               .n_attr = ARRAY_SIZE(mt7530_vlan), 
     4726+       }, 
     4727+       .get_vlan_ports = mt7530_get_vlan_ports, 
     4728+       .set_vlan_ports = mt7530_set_vlan_ports, 
     4729+       .get_port_pvid = mt7530_get_port_pvid, 
     4730+       .set_port_pvid = mt7530_set_port_pvid, 
     4731+       .get_port_link = mt7530_get_port_link, 
     4732+       .apply_config = mt7530_apply_config, 
     4733+       .reset_switch = mt7530_reset_switch, 
     4734+}; 
     4735+ 
     4736+int 
     4737+mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus) 
     4738+{ 
     4739+       struct switch_dev *swdev; 
     4740+       struct mt7530_priv *mt7530; 
     4741+       struct mt7530_mapping *map; 
     4742+       int ret; 
     4743+ 
     4744+       if (bus && bus->phy_map[0x1f]->phy_id != 0x1beef) 
     4745+               return 0; 
     4746+ 
     4747+       mt7530 = devm_kzalloc(dev, sizeof(struct mt7530_priv), GFP_KERNEL); 
     4748+       if (!mt7530) 
     4749+               return -ENOMEM; 
     4750+ 
     4751+       mt7530->base = base; 
     4752+       mt7530->bus = bus; 
     4753+       mt7530->global_vlan_enable = 1; 
     4754+ 
     4755+       swdev = &mt7530->swdev; 
     4756+       swdev->name = "mt7530"; 
     4757+       swdev->alias = "mt7530"; 
     4758+       swdev->cpu_port = MT7530_CPU_PORT; 
     4759+       swdev->ports = MT7530_NUM_PORTS; 
     4760+       swdev->vlans = MT7530_NUM_VLANS; 
     4761+       swdev->ops = &mt7530_ops; 
     4762+ 
     4763+       ret = register_switch(swdev, NULL); 
     4764+       if (ret) { 
     4765+               dev_err(dev, "failed to register mt7530\n"); 
     4766+               return ret; 
     4767+       } 
     4768+ 
     4769+       dev_info(dev, "loaded mt7530 driver\n"); 
     4770+ 
     4771+       map = mt7530_find_mapping(dev->of_node); 
     4772+       if (map) 
     4773+               mt7530_apply_mapping(mt7530, map); 
     4774+       mt7530_apply_config(swdev); 
     4775+ 
     4776+       return 0; 
     4777+} 
     4778+ 
     4779+int 
     4780+mt7530_probe_mmio(struct device *dev, void __iomem *base) 
     4781+{ 
     4782+       return 0; 
     4783+} 
Note: See TracChangeset for help on using the changeset viewer.