Commit 86e8b070 authored by Vignesh Raghavendra's avatar Vignesh Raghavendra Committed by David S. Miller

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

J721e, J7200 and AM64 have multi port switches which can work in multi
mac mode and in switch mode. Add support for configuring this HW in
switch mode using devlink and switchdev notifiers.

Support is similar to existing CPSW switchdev implementation of TI's 32 bit
platform like AM33/AM43/AM57.

To enable switch mode:
devlink dev param set platform/8000000.ethernet name switch_mode value true cmode runtime

All configuration is implemented via switchdev API and notifiers.
Supported:
      - SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS
      - SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS
      - SWITCHDEV_ATTR_ID_PORT_STP_STATE
      - SWITCHDEV_OBJ_ID_PORT_VLAN
      - SWITCHDEV_OBJ_ID_PORT_MDB
      - SWITCHDEV_OBJ_ID_HOST_MDB

Hence AM65 CPSW switchdev driver supports:
     - FDB offloading
     - MDB offloading
     - VLAN filtering and offloading
     - STP
Signed-off-by: default avatarVignesh Raghavendra <vigneshr@ti.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2934db9b
...@@ -26,4 +26,5 @@ keystone_netcp_ethss-y := netcp_ethss.o netcp_sgmii.o netcp_xgbepcsr.o cpsw_ale. ...@@ -26,4 +26,5 @@ keystone_netcp_ethss-y := netcp_ethss.o netcp_sgmii.o netcp_xgbepcsr.o cpsw_ale.
obj-$(CONFIG_TI_K3_AM65_CPSW_NUSS) += ti-am65-cpsw-nuss.o obj-$(CONFIG_TI_K3_AM65_CPSW_NUSS) += ti-am65-cpsw-nuss.o
ti-am65-cpsw-nuss-y := am65-cpsw-nuss.o cpsw_sl.o am65-cpsw-ethtool.o cpsw_ale.o k3-cppi-desc-pool.o am65-cpsw-qos.o ti-am65-cpsw-nuss-y := am65-cpsw-nuss.o cpsw_sl.o am65-cpsw-ethtool.o cpsw_ale.o k3-cppi-desc-pool.o am65-cpsw-qos.o
ti-am65-cpsw-nuss-$(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV) += am65-cpsw-switchdev.o
obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "cpsw_ale.h" #include "cpsw_ale.h"
#include "cpsw_sl.h" #include "cpsw_sl.h"
#include "am65-cpsw-nuss.h" #include "am65-cpsw-nuss.h"
#include "am65-cpsw-switchdev.h"
#include "k3-cppi-desc-pool.h" #include "k3-cppi-desc-pool.h"
#include "am65-cpts.h" #include "am65-cpts.h"
...@@ -228,6 +229,9 @@ static int am65_cpsw_nuss_ndo_slave_add_vid(struct net_device *ndev, ...@@ -228,6 +229,9 @@ static int am65_cpsw_nuss_ndo_slave_add_vid(struct net_device *ndev,
u32 port_mask, unreg_mcast = 0; u32 port_mask, unreg_mcast = 0;
int ret; int ret;
if (!common->is_emac_mode)
return 0;
if (!netif_running(ndev) || !vid) if (!netif_running(ndev) || !vid)
return 0; return 0;
...@@ -255,6 +259,9 @@ static int am65_cpsw_nuss_ndo_slave_kill_vid(struct net_device *ndev, ...@@ -255,6 +259,9 @@ static int am65_cpsw_nuss_ndo_slave_kill_vid(struct net_device *ndev,
struct am65_cpsw_port *port = am65_ndev_to_port(ndev); struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
int ret; int ret;
if (!common->is_emac_mode)
return 0;
if (!netif_running(ndev) || !vid) if (!netif_running(ndev) || !vid)
return 0; return 0;
...@@ -277,6 +284,11 @@ static void am65_cpsw_slave_set_promisc(struct am65_cpsw_port *port, ...@@ -277,6 +284,11 @@ static void am65_cpsw_slave_set_promisc(struct am65_cpsw_port *port,
{ {
struct am65_cpsw_common *common = port->common; struct am65_cpsw_common *common = port->common;
if (promisc && !common->is_emac_mode) {
dev_dbg(common->dev, "promisc mode requested in switch mode");
return;
}
if (promisc) { if (promisc) {
/* Enable promiscuous mode */ /* Enable promiscuous mode */
cpsw_ale_control_set(common->ale, port->port_id, cpsw_ale_control_set(common->ale, port->port_id,
...@@ -800,12 +812,13 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_common *common, ...@@ -800,12 +812,13 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_common *common,
new_skb = netdev_alloc_skb_ip_align(ndev, AM65_CPSW_MAX_PACKET_SIZE); new_skb = netdev_alloc_skb_ip_align(ndev, AM65_CPSW_MAX_PACKET_SIZE);
if (new_skb) { if (new_skb) {
ndev_priv = netdev_priv(ndev);
am65_cpsw_nuss_set_offload_fwd_mark(skb, ndev_priv->offload_fwd_mark);
skb_put(skb, pkt_len); skb_put(skb, pkt_len);
skb->protocol = eth_type_trans(skb, ndev); skb->protocol = eth_type_trans(skb, ndev);
am65_cpsw_nuss_rx_csum(skb, csum_info); am65_cpsw_nuss_rx_csum(skb, csum_info);
napi_gro_receive(&common->napi_rx, skb); napi_gro_receive(&common->napi_rx, skb);
ndev_priv = netdev_priv(ndev);
stats = this_cpu_ptr(ndev_priv->stats); stats = this_cpu_ptr(ndev_priv->stats);
u64_stats_update_begin(&stats->syncp); u64_stats_update_begin(&stats->syncp);
...@@ -2144,6 +2157,10 @@ static int am65_cpsw_register_notifiers(struct am65_cpsw_common *cpsw) ...@@ -2144,6 +2157,10 @@ static int am65_cpsw_register_notifiers(struct am65_cpsw_common *cpsw)
return ret; return ret;
} }
ret = am65_cpsw_switchdev_register_notifiers(cpsw);
if (ret)
unregister_netdevice_notifier(&cpsw->am65_cpsw_netdevice_nb);
return ret; return ret;
} }
...@@ -2153,6 +2170,7 @@ static void am65_cpsw_unregister_notifiers(struct am65_cpsw_common *cpsw) ...@@ -2153,6 +2170,7 @@ static void am65_cpsw_unregister_notifiers(struct am65_cpsw_common *cpsw)
!IS_REACHABLE(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV)) !IS_REACHABLE(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV))
return; return;
am65_cpsw_switchdev_unregister_notifiers(cpsw);
unregister_netdevice_notifier(&cpsw->am65_cpsw_netdevice_nb); unregister_netdevice_notifier(&cpsw->am65_cpsw_netdevice_nb);
} }
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef DRIVERS_NET_ETHERNET_TI_AM65_CPSW_SWITCHDEV_H_
#define DRIVERS_NET_ETHERNET_TI_AM65_CPSW_SWITCHDEV_H_
#include <linux/skbuff.h>
#if IS_ENABLED(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV)
static inline void am65_cpsw_nuss_set_offload_fwd_mark(struct sk_buff *skb, bool val)
{
skb->offload_fwd_mark = val;
}
int am65_cpsw_switchdev_register_notifiers(struct am65_cpsw_common *cpsw);
void am65_cpsw_switchdev_unregister_notifiers(struct am65_cpsw_common *cpsw);
#else
static inline int am65_cpsw_switchdev_register_notifiers(struct am65_cpsw_common *cpsw)
{
return -EOPNOTSUPP;
}
static inline void am65_cpsw_switchdev_unregister_notifiers(struct am65_cpsw_common *cpsw)
{
}
static inline void am65_cpsw_nuss_set_offload_fwd_mark(struct sk_buff *skb, bool val)
{
}
#endif
#endif /* DRIVERS_NET_ETHERNET_TI_AM65_CPSW_SWITCHDEV_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment