Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: ti: am65-cpsw-nuss: Add devlink support

AM65 NUSS ethernet switch on K3 devices can be configured to work either
in independent mac mode where each port acts as independent network
interface (multi mac) or switch mode.

Add devlink hooks to provide a way to switch b/w these modes.

Rationale to use devlink instead of defaulting to bridge mode is that
SoC use cases require to support multiple independent MAC ports with no
switching so that users can use software bridges with multi-mac
configuration (e.g: to support LAG, HSR/PRP, etc). Also, switching
between multi mac and switch mode requires significant Port and ALE
reconfiguration, therefore is easier to be made as part of mode change
devlink hooks. It also allows to keep user interface similar to what
was implemented for the previous generation of TI CPSW IP
(on AM33/AM43/AM57 SoCs).

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Vignesh Raghavendra and committed by
David S. Miller
58356eb3 b4e18b29

+404 -18
+26
Documentation/networking/devlink/am65-nuss-cpsw-switch.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + ============================== 4 + am65-cpsw-nuss devlink support 5 + ============================== 6 + 7 + This document describes the devlink features implemented by the ``am65-cpsw-nuss`` 8 + device driver. 9 + 10 + Parameters 11 + ========== 12 + 13 + The ``am65-cpsw-nuss`` driver implements the following driver-specific 14 + parameters. 15 + 16 + .. list-table:: Driver-specific parameters implemented 17 + :widths: 5 5 5 85 18 + 19 + * - Name 20 + - Type 21 + - Mode 22 + - Description 23 + * - ``switch_mode`` 24 + - Boolean 25 + - runtime 26 + - Enable switch mode
+1
Documentation/networking/devlink/index.rst
··· 45 45 sja1105 46 46 qed 47 47 ti-cpsw-switch 48 + am65-nuss-cpsw-switch
+10
drivers/net/ethernet/ti/Kconfig
··· 92 92 config TI_K3_AM65_CPSW_NUSS 93 93 tristate "TI K3 AM654x/J721E CPSW Ethernet driver" 94 94 depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER 95 + select NET_DEVLINK 95 96 select TI_DAVINCI_MDIO 96 97 imply PHY_TI_GMII_SEL 97 98 depends on TI_K3_AM65_CPTS || !TI_K3_AM65_CPTS ··· 105 104 106 105 To compile this driver as a module, choose M here: the module 107 106 will be called ti-am65-cpsw-nuss. 107 + 108 + config TI_K3_AM65_CPSW_SWITCHDEV 109 + bool "TI K3 AM654x/J721E CPSW Switch mode support" 110 + depends on TI_K3_AM65_CPSW_NUSS 111 + depends on NET_SWITCHDEV 112 + help 113 + This enables switchdev support for TI K3 CPSWxG Ethernet 114 + Switch. Enable this driver to support hardware switch support for AM65 115 + CPSW NUSS driver. 108 116 109 117 config TI_K3_AM65_CPTS 110 118 tristate "TI K3 AM65x CPTS"
+345 -18
drivers/net/ethernet/ti/am65-cpsw-nuss.c
··· 408 408 writel(val, host_p->port_base + AM65_CPSW_PORT_REG_PRI_CTL); 409 409 } 410 410 411 + static void am65_cpsw_init_host_port_switch(struct am65_cpsw_common *common); 412 + static void am65_cpsw_init_host_port_emac(struct am65_cpsw_common *common); 413 + static void am65_cpsw_init_port_switch_ale(struct am65_cpsw_port *port); 414 + static void am65_cpsw_init_port_emac_ale(struct am65_cpsw_port *port); 415 + 411 416 static int am65_cpsw_nuss_common_open(struct am65_cpsw_common *common, 412 417 netdev_features_t features) 413 418 { ··· 459 454 ALE_DEFAULT_THREAD_ID, 0); 460 455 cpsw_ale_control_set(common->ale, HOST_PORT_NUM, 461 456 ALE_DEFAULT_THREAD_ENABLE, 1); 462 - if (AM65_CPSW_IS_CPSW2G(common)) 463 - cpsw_ale_control_set(common->ale, HOST_PORT_NUM, 464 - ALE_PORT_NOLEARN, 1); 465 457 /* switch to vlan unaware mode */ 466 458 cpsw_ale_control_set(common->ale, HOST_PORT_NUM, ALE_VLAN_AWARE, 1); 467 459 cpsw_ale_control_set(common->ale, HOST_PORT_NUM, ··· 471 469 cpsw_ale_add_vlan(common->ale, 0, port_mask, 472 470 port_mask, port_mask, 473 471 port_mask & ~ALE_PORT_HOST); 472 + 473 + if (common->is_emac_mode) 474 + am65_cpsw_init_host_port_emac(common); 475 + else 476 + am65_cpsw_init_host_port_switch(common); 474 477 475 478 for (i = 0; i < common->rx_chns.descs_num; i++) { 476 479 skb = __netdev_alloc_skb_ip_align(NULL, ··· 605 598 { 606 599 struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 607 600 struct am65_cpsw_port *port = am65_ndev_to_port(ndev); 608 - u32 port_mask; 609 601 int ret, i; 610 602 611 603 ret = pm_runtime_get_sync(common->dev); ··· 637 631 638 632 am65_cpsw_port_set_sl_mac(port, ndev->dev_addr); 639 633 640 - if (port->slave.mac_only) { 641 - /* enable mac-only mode on port */ 642 - cpsw_ale_control_set(common->ale, port->port_id, 643 - ALE_PORT_MACONLY, 1); 644 - cpsw_ale_control_set(common->ale, port->port_id, 645 - ALE_PORT_NOLEARN, 1); 646 - } 647 - 648 - port_mask = BIT(port->port_id) | ALE_PORT_HOST; 649 - cpsw_ale_add_ucast(common->ale, ndev->dev_addr, 650 - HOST_PORT_NUM, ALE_SECURE, 0); 651 - cpsw_ale_add_mcast(common->ale, ndev->broadcast, 652 - port_mask, 0, 0, ALE_MCAST_FWD_2); 634 + if (common->is_emac_mode) 635 + am65_cpsw_init_port_emac_ale(port); 636 + else 637 + am65_cpsw_init_port_switch_ale(port); 653 638 654 639 /* mac_sl should be configured via phy-link interface */ 655 640 am65_cpsw_sl_ctl_reset(port); ··· 1448 1451 stats->tx_dropped = dev->stats.tx_dropped; 1449 1452 } 1450 1453 1454 + static struct devlink_port *am65_cpsw_ndo_get_devlink_port(struct net_device *ndev) 1455 + { 1456 + struct am65_cpsw_port *port = am65_ndev_to_port(ndev); 1457 + 1458 + return &port->devlink_port; 1459 + } 1460 + 1451 1461 static const struct net_device_ops am65_cpsw_nuss_netdev_ops = { 1452 1462 .ndo_open = am65_cpsw_nuss_ndo_slave_open, 1453 1463 .ndo_stop = am65_cpsw_nuss_ndo_slave_stop, ··· 1468 1464 .ndo_vlan_rx_kill_vid = am65_cpsw_nuss_ndo_slave_kill_vid, 1469 1465 .ndo_do_ioctl = am65_cpsw_nuss_ndo_slave_ioctl, 1470 1466 .ndo_setup_tc = am65_cpsw_qos_ndo_setup_tc, 1467 + .ndo_get_devlink_port = am65_cpsw_ndo_get_devlink_port, 1471 1468 }; 1472 1469 1473 1470 static void am65_cpsw_nuss_slave_disable_unused(struct am65_cpsw_port *port) ··· 2036 2031 } 2037 2032 } 2038 2033 2034 + static const struct devlink_ops am65_cpsw_devlink_ops = {}; 2035 + 2036 + static void am65_cpsw_init_stp_ale_entry(struct am65_cpsw_common *cpsw) 2037 + { 2038 + cpsw_ale_add_mcast(cpsw->ale, eth_stp_addr, ALE_PORT_HOST, ALE_SUPER, 0, 2039 + ALE_MCAST_BLOCK_LEARN_FWD); 2040 + } 2041 + 2042 + static void am65_cpsw_init_host_port_switch(struct am65_cpsw_common *common) 2043 + { 2044 + struct am65_cpsw_host *host = am65_common_get_host(common); 2045 + 2046 + writel(common->default_vlan, host->port_base + AM65_CPSW_PORT_VLAN_REG_OFFSET); 2047 + 2048 + am65_cpsw_init_stp_ale_entry(common); 2049 + 2050 + cpsw_ale_control_set(common->ale, HOST_PORT_NUM, ALE_P0_UNI_FLOOD, 1); 2051 + dev_dbg(common->dev, "Set P0_UNI_FLOOD\n"); 2052 + cpsw_ale_control_set(common->ale, HOST_PORT_NUM, ALE_PORT_NOLEARN, 0); 2053 + } 2054 + 2055 + static void am65_cpsw_init_host_port_emac(struct am65_cpsw_common *common) 2056 + { 2057 + struct am65_cpsw_host *host = am65_common_get_host(common); 2058 + 2059 + writel(0, host->port_base + AM65_CPSW_PORT_VLAN_REG_OFFSET); 2060 + 2061 + cpsw_ale_control_set(common->ale, HOST_PORT_NUM, ALE_P0_UNI_FLOOD, 0); 2062 + dev_dbg(common->dev, "unset P0_UNI_FLOOD\n"); 2063 + 2064 + /* learning make no sense in multi-mac mode */ 2065 + cpsw_ale_control_set(common->ale, HOST_PORT_NUM, ALE_PORT_NOLEARN, 1); 2066 + } 2067 + 2068 + static int am65_cpsw_dl_switch_mode_get(struct devlink *dl, u32 id, 2069 + struct devlink_param_gset_ctx *ctx) 2070 + { 2071 + struct am65_cpsw_devlink *dl_priv = devlink_priv(dl); 2072 + struct am65_cpsw_common *common = dl_priv->common; 2073 + 2074 + dev_dbg(common->dev, "%s id:%u\n", __func__, id); 2075 + 2076 + if (id != AM65_CPSW_DL_PARAM_SWITCH_MODE) 2077 + return -EOPNOTSUPP; 2078 + 2079 + ctx->val.vbool = !common->is_emac_mode; 2080 + 2081 + return 0; 2082 + } 2083 + 2084 + static void am65_cpsw_init_port_emac_ale(struct am65_cpsw_port *port) 2085 + { 2086 + struct am65_cpsw_slave_data *slave = &port->slave; 2087 + struct am65_cpsw_common *common = port->common; 2088 + u32 port_mask; 2089 + 2090 + writel(slave->port_vlan, port->port_base + AM65_CPSW_PORT_VLAN_REG_OFFSET); 2091 + 2092 + if (slave->mac_only) 2093 + /* enable mac-only mode on port */ 2094 + cpsw_ale_control_set(common->ale, port->port_id, 2095 + ALE_PORT_MACONLY, 1); 2096 + 2097 + cpsw_ale_control_set(common->ale, port->port_id, ALE_PORT_NOLEARN, 1); 2098 + 2099 + port_mask = BIT(port->port_id) | ALE_PORT_HOST; 2100 + 2101 + cpsw_ale_add_ucast(common->ale, port->ndev->dev_addr, 2102 + HOST_PORT_NUM, ALE_SECURE, slave->port_vlan); 2103 + cpsw_ale_add_mcast(common->ale, port->ndev->broadcast, 2104 + port_mask, ALE_VLAN, slave->port_vlan, ALE_MCAST_FWD_2); 2105 + } 2106 + 2107 + static void am65_cpsw_init_port_switch_ale(struct am65_cpsw_port *port) 2108 + { 2109 + struct am65_cpsw_slave_data *slave = &port->slave; 2110 + struct am65_cpsw_common *cpsw = port->common; 2111 + u32 port_mask; 2112 + 2113 + cpsw_ale_control_set(cpsw->ale, port->port_id, 2114 + ALE_PORT_NOLEARN, 0); 2115 + 2116 + cpsw_ale_add_ucast(cpsw->ale, port->ndev->dev_addr, 2117 + HOST_PORT_NUM, ALE_SECURE | ALE_BLOCKED | ALE_VLAN, 2118 + slave->port_vlan); 2119 + 2120 + port_mask = BIT(port->port_id) | ALE_PORT_HOST; 2121 + 2122 + cpsw_ale_add_mcast(cpsw->ale, port->ndev->broadcast, 2123 + port_mask, ALE_VLAN, slave->port_vlan, 2124 + ALE_MCAST_FWD_2); 2125 + 2126 + writel(slave->port_vlan, port->port_base + AM65_CPSW_PORT_VLAN_REG_OFFSET); 2127 + 2128 + cpsw_ale_control_set(cpsw->ale, port->port_id, 2129 + ALE_PORT_MACONLY, 0); 2130 + } 2131 + 2132 + static int am65_cpsw_dl_switch_mode_set(struct devlink *dl, u32 id, 2133 + struct devlink_param_gset_ctx *ctx) 2134 + { 2135 + struct am65_cpsw_devlink *dl_priv = devlink_priv(dl); 2136 + struct am65_cpsw_common *cpsw = dl_priv->common; 2137 + bool switch_en = ctx->val.vbool; 2138 + bool if_running = false; 2139 + int i; 2140 + 2141 + dev_dbg(cpsw->dev, "%s id:%u\n", __func__, id); 2142 + 2143 + if (id != AM65_CPSW_DL_PARAM_SWITCH_MODE) 2144 + return -EOPNOTSUPP; 2145 + 2146 + if (switch_en == !cpsw->is_emac_mode) 2147 + return 0; 2148 + 2149 + if (!switch_en && cpsw->br_members) { 2150 + dev_err(cpsw->dev, "Remove ports from bridge before disabling switch mode\n"); 2151 + return -EINVAL; 2152 + } 2153 + 2154 + rtnl_lock(); 2155 + 2156 + cpsw->is_emac_mode = !switch_en; 2157 + 2158 + for (i = 0; i < cpsw->port_num; i++) { 2159 + struct net_device *sl_ndev = cpsw->ports[i].ndev; 2160 + 2161 + if (!sl_ndev || !netif_running(sl_ndev)) 2162 + continue; 2163 + 2164 + if_running = true; 2165 + } 2166 + 2167 + if (!if_running) { 2168 + /* all ndevs are down */ 2169 + for (i = 0; i < cpsw->port_num; i++) { 2170 + struct net_device *sl_ndev = cpsw->ports[i].ndev; 2171 + struct am65_cpsw_slave_data *slave; 2172 + 2173 + if (!sl_ndev) 2174 + continue; 2175 + 2176 + slave = am65_ndev_to_slave(sl_ndev); 2177 + if (switch_en) 2178 + slave->port_vlan = cpsw->default_vlan; 2179 + else 2180 + slave->port_vlan = 0; 2181 + } 2182 + 2183 + goto exit; 2184 + } 2185 + 2186 + cpsw_ale_control_set(cpsw->ale, 0, ALE_BYPASS, 1); 2187 + /* clean up ALE table */ 2188 + cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_CLEAR, 1); 2189 + cpsw_ale_control_get(cpsw->ale, HOST_PORT_NUM, ALE_AGEOUT); 2190 + 2191 + if (switch_en) { 2192 + dev_info(cpsw->dev, "Enable switch mode\n"); 2193 + 2194 + am65_cpsw_init_host_port_switch(cpsw); 2195 + 2196 + for (i = 0; i < cpsw->port_num; i++) { 2197 + struct net_device *sl_ndev = cpsw->ports[i].ndev; 2198 + struct am65_cpsw_slave_data *slave; 2199 + struct am65_cpsw_port *port; 2200 + 2201 + if (!sl_ndev) 2202 + continue; 2203 + 2204 + port = am65_ndev_to_port(sl_ndev); 2205 + slave = am65_ndev_to_slave(sl_ndev); 2206 + slave->port_vlan = cpsw->default_vlan; 2207 + 2208 + if (netif_running(sl_ndev)) 2209 + am65_cpsw_init_port_switch_ale(port); 2210 + } 2211 + 2212 + } else { 2213 + dev_info(cpsw->dev, "Disable switch mode\n"); 2214 + 2215 + am65_cpsw_init_host_port_emac(cpsw); 2216 + 2217 + for (i = 0; i < cpsw->port_num; i++) { 2218 + struct net_device *sl_ndev = cpsw->ports[i].ndev; 2219 + struct am65_cpsw_port *port; 2220 + 2221 + if (!sl_ndev) 2222 + continue; 2223 + 2224 + port = am65_ndev_to_port(sl_ndev); 2225 + port->slave.port_vlan = 0; 2226 + if (netif_running(sl_ndev)) 2227 + am65_cpsw_init_port_emac_ale(port); 2228 + } 2229 + } 2230 + cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_BYPASS, 0); 2231 + exit: 2232 + rtnl_unlock(); 2233 + 2234 + return 0; 2235 + } 2236 + 2237 + static const struct devlink_param am65_cpsw_devlink_params[] = { 2238 + DEVLINK_PARAM_DRIVER(AM65_CPSW_DL_PARAM_SWITCH_MODE, "switch_mode", 2239 + DEVLINK_PARAM_TYPE_BOOL, 2240 + BIT(DEVLINK_PARAM_CMODE_RUNTIME), 2241 + am65_cpsw_dl_switch_mode_get, 2242 + am65_cpsw_dl_switch_mode_set, NULL), 2243 + }; 2244 + 2245 + static void am65_cpsw_unregister_devlink_ports(struct am65_cpsw_common *common) 2246 + { 2247 + struct devlink_port *dl_port; 2248 + struct am65_cpsw_port *port; 2249 + int i; 2250 + 2251 + for (i = 1; i <= common->port_num; i++) { 2252 + port = am65_common_get_port(common, i); 2253 + dl_port = &port->devlink_port; 2254 + 2255 + if (dl_port->registered) 2256 + devlink_port_unregister(dl_port); 2257 + } 2258 + } 2259 + 2260 + static int am65_cpsw_nuss_register_devlink(struct am65_cpsw_common *common) 2261 + { 2262 + struct devlink_port_attrs attrs = {}; 2263 + struct am65_cpsw_devlink *dl_priv; 2264 + struct device *dev = common->dev; 2265 + struct devlink_port *dl_port; 2266 + struct am65_cpsw_port *port; 2267 + int ret = 0; 2268 + int i; 2269 + 2270 + common->devlink = 2271 + devlink_alloc(&am65_cpsw_devlink_ops, sizeof(*dl_priv)); 2272 + if (!common->devlink) 2273 + return -ENOMEM; 2274 + 2275 + dl_priv = devlink_priv(common->devlink); 2276 + dl_priv->common = common; 2277 + 2278 + ret = devlink_register(common->devlink, dev); 2279 + if (ret) { 2280 + dev_err(dev, "devlink reg fail ret:%d\n", ret); 2281 + goto dl_free; 2282 + } 2283 + 2284 + /* Provide devlink hook to switch mode when multiple external ports 2285 + * are present NUSS switchdev driver is enabled. 2286 + */ 2287 + if (!AM65_CPSW_IS_CPSW2G(common) && 2288 + IS_ENABLED(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV)) { 2289 + ret = devlink_params_register(common->devlink, 2290 + am65_cpsw_devlink_params, 2291 + ARRAY_SIZE(am65_cpsw_devlink_params)); 2292 + if (ret) { 2293 + dev_err(dev, "devlink params reg fail ret:%d\n", ret); 2294 + goto dl_unreg; 2295 + } 2296 + devlink_params_publish(common->devlink); 2297 + } 2298 + 2299 + for (i = 1; i <= common->port_num; i++) { 2300 + port = am65_common_get_port(common, i); 2301 + dl_port = &port->devlink_port; 2302 + 2303 + attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 2304 + attrs.phys.port_number = port->port_id; 2305 + attrs.switch_id.id_len = sizeof(resource_size_t); 2306 + memcpy(attrs.switch_id.id, common->switch_id, attrs.switch_id.id_len); 2307 + devlink_port_attrs_set(dl_port, &attrs); 2308 + 2309 + ret = devlink_port_register(common->devlink, dl_port, port->port_id); 2310 + if (ret) { 2311 + dev_err(dev, "devlink_port reg fail for port %d, ret:%d\n", 2312 + port->port_id, ret); 2313 + goto dl_port_unreg; 2314 + } 2315 + devlink_port_type_eth_set(dl_port, port->ndev); 2316 + } 2317 + 2318 + return ret; 2319 + 2320 + dl_port_unreg: 2321 + am65_cpsw_unregister_devlink_ports(common); 2322 + dl_unreg: 2323 + devlink_unregister(common->devlink); 2324 + dl_free: 2325 + devlink_free(common->devlink); 2326 + 2327 + return ret; 2328 + } 2329 + 2330 + static void am65_cpsw_unregister_devlink(struct am65_cpsw_common *common) 2331 + { 2332 + if (!AM65_CPSW_IS_CPSW2G(common) && 2333 + IS_ENABLED(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV)) { 2334 + devlink_params_unpublish(common->devlink); 2335 + devlink_params_unregister(common->devlink, am65_cpsw_devlink_params, 2336 + ARRAY_SIZE(am65_cpsw_devlink_params)); 2337 + } 2338 + 2339 + am65_cpsw_unregister_devlink_ports(common); 2340 + devlink_unregister(common->devlink); 2341 + devlink_free(common->devlink); 2342 + } 2343 + 2039 2344 static int am65_cpsw_nuss_register_ndevs(struct am65_cpsw_common *common) 2040 2345 { 2041 2346 struct device *dev = common->dev; ··· 2379 2064 } 2380 2065 } 2381 2066 2067 + ret = am65_cpsw_nuss_register_devlink(common); 2068 + if (ret) 2069 + goto err_cleanup_ndev; 2382 2070 2383 2071 /* can't auto unregister ndev using devm_add_action() due to 2384 2072 * devres release sequence in DD core for DMA 2385 2073 */ 2386 - return 0; 2387 2074 2075 + return 0; 2388 2076 err_cleanup_ndev: 2389 2077 am65_cpsw_nuss_cleanup_ndev(common); 2390 2078 return ret; ··· 2469 2151 struct device_node *node; 2470 2152 struct resource *res; 2471 2153 struct clk *clk; 2154 + u64 id_temp; 2472 2155 int ret, i; 2473 2156 2474 2157 common = devm_kzalloc(dev, sizeof(struct am65_cpsw_common), GFP_KERNEL); ··· 2489 2170 if (IS_ERR(common->ss_base)) 2490 2171 return PTR_ERR(common->ss_base); 2491 2172 common->cpsw_base = common->ss_base + AM65_CPSW_CPSW_NU_BASE; 2173 + /* Use device's physical base address as switch id */ 2174 + id_temp = cpu_to_be64(res->start); 2175 + memcpy(common->switch_id, &id_temp, sizeof(res->start)); 2492 2176 2493 2177 node = of_get_child_by_name(dev->of_node, "ethernet-ports"); 2494 2178 if (!node) ··· 2505 2183 init_completion(&common->tdown_complete); 2506 2184 common->tx_ch_num = 1; 2507 2185 common->pf_p0_rx_ptype_rrobin = false; 2186 + common->default_vlan = 1; 2508 2187 2509 2188 common->ports = devm_kcalloc(dev, common->port_num, 2510 2189 sizeof(*common->ports), ··· 2585 2262 2586 2263 dev_set_drvdata(dev, common); 2587 2264 2265 + common->is_emac_mode = true; 2266 + 2588 2267 ret = am65_cpsw_nuss_init_ndevs(common); 2589 2268 if (ret) 2590 2269 goto err_of_clear; ··· 2619 2294 pm_runtime_put_noidle(&pdev->dev); 2620 2295 return ret; 2621 2296 } 2297 + 2298 + am65_cpsw_unregister_devlink(common); 2622 2299 2623 2300 /* must unregister ndevs here because DD release_driver routine calls 2624 2301 * dma_deconfigure(dev) before devres_release_all(dev)
+22
drivers/net/ethernet/ti/am65-cpsw-nuss.h
··· 6 6 #ifndef AM65_CPSW_NUSS_H_ 7 7 #define AM65_CPSW_NUSS_H_ 8 8 9 + #include <linux/if_ether.h> 9 10 #include <linux/kernel.h> 10 11 #include <linux/module.h> 11 12 #include <linux/netdevice.h> 12 13 #include <linux/phy.h> 13 14 #include <linux/platform_device.h> 14 15 #include <linux/soc/ti/k3-ringacc.h> 16 + #include <net/devlink.h> 15 17 #include "am65-cpsw-qos.h" 16 18 17 19 struct am65_cpts; ··· 23 21 #define AM65_CPSW_MAX_TX_QUEUES 8 24 22 #define AM65_CPSW_MAX_RX_QUEUES 1 25 23 #define AM65_CPSW_MAX_RX_FLOWS 1 24 + 25 + #define AM65_CPSW_PORT_VLAN_REG_OFFSET 0x014 26 26 27 27 struct am65_cpsw_slave_data { 28 28 bool mac_only; ··· 36 32 bool rx_pause; 37 33 bool tx_pause; 38 34 u8 mac_addr[ETH_ALEN]; 35 + int port_vlan; 39 36 }; 40 37 41 38 struct am65_cpsw_port { ··· 52 47 bool tx_ts_enabled; 53 48 bool rx_ts_enabled; 54 49 struct am65_cpsw_qos qos; 50 + struct devlink_port devlink_port; 55 51 }; 56 52 57 53 struct am65_cpsw_host { ··· 91 85 const char *ale_dev_id; 92 86 }; 93 87 88 + enum cpsw_devlink_param_id { 89 + AM65_CPSW_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, 90 + AM65_CPSW_DL_PARAM_SWITCH_MODE, 91 + }; 92 + 93 + struct am65_cpsw_devlink { 94 + struct am65_cpsw_common *common; 95 + }; 96 + 94 97 struct am65_cpsw_common { 95 98 struct device *dev; 96 99 struct device *mdio_dev; ··· 132 117 bool pf_p0_rx_ptype_rrobin; 133 118 struct am65_cpts *cpts; 134 119 int est_enabled; 120 + 121 + bool is_emac_mode; 122 + u16 br_members; 123 + int default_vlan; 124 + struct devlink *devlink; 125 + unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN]; 135 126 }; 136 127 137 128 struct am65_cpsw_ndev_stats { ··· 152 131 u32 msg_enable; 153 132 struct am65_cpsw_port *port; 154 133 struct am65_cpsw_ndev_stats __percpu *stats; 134 + bool offload_fwd_mark; 155 135 }; 156 136 157 137 #define am65_ndev_to_priv(ndev) \