Commit f79bebad authored by David S. Miller's avatar David S. Miller

Merge branch 'am65-cpsw-nuss-switchdev-driver'

Vignesh Raghavendra says:

====================
net: ti: am65-cpsw-nuss: Add switchdev driver

This series adds switchdev support for AM65 CPSW NUSS driver to support
multi port CPSW present on J721e and AM64 SoCs.
It adds devlink hook to switch b/w switch mode and multi mac mode.

v2:
Rebased on latest net-next
Update patch 1/4 with rationale for using devlink
====================
parents b4e18b29 e276cfb9
...@@ -49,6 +49,7 @@ Contents: ...@@ -49,6 +49,7 @@ Contents:
stmicro/stmmac stmicro/stmmac
ti/cpsw ti/cpsw
ti/cpsw_switchdev ti/cpsw_switchdev
ti/am65_nuss_cpsw_switchdev
ti/tlan ti/tlan
toshiba/spider_net toshiba/spider_net
......
.. SPDX-License-Identifier: GPL-2.0
===================================================================
Texas Instruments K3 AM65 CPSW NUSS switchdev based ethernet driver
===================================================================
:Version: 1.0
Port renaming
=============
In order to rename via udev::
ip -d link show dev sw0p1 | grep switchid
SUBSYSTEM=="net", ACTION=="add", ATTR{phys_switch_id}==<switchid>, \
ATTR{phys_port_name}!="", NAME="sw0$attr{phys_port_name}"
Multi mac mode
==============
- The driver is operating in multi-mac mode by default, thus
working as N individual network interfaces.
Devlink configuration parameters
================================
See Documentation/networking/devlink/am65-nuss-cpsw-switch.rst
Enabling "switch"
=================
The Switch mode can be enabled by configuring devlink driver parameter
"switch_mode" to 1/true::
devlink dev param set platform/c000000.ethernet \
name switch_mode value true cmode runtime
This can be done regardless of the state of Port's netdev devices - UP/DOWN, but
Port's netdev devices have to be in UP before joining to the bridge to avoid
overwriting of bridge configuration as CPSW switch driver completely reloads its
configuration when first port changes its state to UP.
When the both interfaces joined the bridge - CPSW switch driver will enable
marking packets with offload_fwd_mark flag.
All configuration is implemented via switchdev API.
Bridge setup
============
::
devlink dev param set platform/c000000.ethernet \
name switch_mode value true cmode runtime
ip link add name br0 type bridge
ip link set dev br0 type bridge ageing_time 1000
ip link set dev sw0p1 up
ip link set dev sw0p2 up
ip link set dev sw0p1 master br0
ip link set dev sw0p2 master br0
[*] bridge vlan add dev br0 vid 1 pvid untagged self
[*] if vlan_filtering=1. where default_pvid=1
Note. Steps [*] are mandatory.
On/off STP
==========
::
ip link set dev BRDEV type bridge stp_state 1/0
VLAN configuration
==================
::
bridge vlan add dev br0 vid 1 pvid untagged self <---- add cpu port to VLAN 1
Note. This step is mandatory for bridge/default_pvid.
Add extra VLANs
===============
1. untagged::
bridge vlan add dev sw0p1 vid 100 pvid untagged master
bridge vlan add dev sw0p2 vid 100 pvid untagged master
bridge vlan add dev br0 vid 100 pvid untagged self <---- Add cpu port to VLAN100
2. tagged::
bridge vlan add dev sw0p1 vid 100 master
bridge vlan add dev sw0p2 vid 100 master
bridge vlan add dev br0 vid 100 pvid tagged self <---- Add cpu port to VLAN100
FDBs
----
FDBs are automatically added on the appropriate switch port upon detection
Manually adding FDBs::
bridge fdb add aa:bb:cc:dd:ee:ff dev sw0p1 master vlan 100
bridge fdb add aa:bb:cc:dd:ee:fe dev sw0p2 master <---- Add on all VLANs
MDBs
----
MDBs are automatically added on the appropriate switch port upon detection
Manually adding MDBs::
bridge mdb add dev br0 port sw0p1 grp 239.1.1.1 permanent vid 100
bridge mdb add dev br0 port sw0p1 grp 239.1.1.1 permanent <---- Add on all VLANs
Multicast flooding
==================
CPU port mcast_flooding is always on
Turning flooding on/off on swithch ports:
bridge link set dev sw0p1 mcast_flood on/off
Access and Trunk port
=====================
::
bridge vlan add dev sw0p1 vid 100 pvid untagged master
bridge vlan add dev sw0p2 vid 100 master
bridge vlan add dev br0 vid 100 self
ip link add link br0 name br0.100 type vlan id 100
Note. Setting PVID on Bridge device itself works only for
default VLAN (default_pvid).
.. SPDX-License-Identifier: GPL-2.0
==============================
am65-cpsw-nuss devlink support
==============================
This document describes the devlink features implemented by the ``am65-cpsw-nuss``
device driver.
Parameters
==========
The ``am65-cpsw-nuss`` driver implements the following driver-specific
parameters.
.. list-table:: Driver-specific parameters implemented
:widths: 5 5 5 85
* - Name
- Type
- Mode
- Description
* - ``switch_mode``
- Boolean
- runtime
- Enable switch mode
...@@ -45,3 +45,4 @@ parameters, info versions, and other features it supports. ...@@ -45,3 +45,4 @@ parameters, info versions, and other features it supports.
sja1105 sja1105
qed qed
ti-cpsw-switch ti-cpsw-switch
am65-nuss-cpsw-switch
...@@ -92,6 +92,7 @@ config TI_CPTS ...@@ -92,6 +92,7 @@ config TI_CPTS
config TI_K3_AM65_CPSW_NUSS config TI_K3_AM65_CPSW_NUSS
tristate "TI K3 AM654x/J721E CPSW Ethernet driver" tristate "TI K3 AM654x/J721E CPSW Ethernet driver"
depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
select NET_DEVLINK
select TI_DAVINCI_MDIO select TI_DAVINCI_MDIO
imply PHY_TI_GMII_SEL imply PHY_TI_GMII_SEL
depends on TI_K3_AM65_CPTS || !TI_K3_AM65_CPTS depends on TI_K3_AM65_CPTS || !TI_K3_AM65_CPTS
...@@ -105,6 +106,15 @@ config TI_K3_AM65_CPSW_NUSS ...@@ -105,6 +106,15 @@ config TI_K3_AM65_CPSW_NUSS
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called ti-am65-cpsw-nuss. will be called ti-am65-cpsw-nuss.
config TI_K3_AM65_CPSW_SWITCHDEV
bool "TI K3 AM654x/J721E CPSW Switch mode support"
depends on TI_K3_AM65_CPSW_NUSS
depends on NET_SWITCHDEV
help
This enables switchdev support for TI K3 CPSWxG Ethernet
Switch. Enable this driver to support hardware switch support for AM65
CPSW NUSS driver.
config TI_K3_AM65_CPTS config TI_K3_AM65_CPTS
tristate "TI K3 AM65x CPTS" tristate "TI K3 AM65x CPTS"
depends on ARCH_K3 && OF depends on ARCH_K3 && OF
......
...@@ -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
This diff is collapsed.
...@@ -6,12 +6,14 @@ ...@@ -6,12 +6,14 @@
#ifndef AM65_CPSW_NUSS_H_ #ifndef AM65_CPSW_NUSS_H_
#define AM65_CPSW_NUSS_H_ #define AM65_CPSW_NUSS_H_
#include <linux/if_ether.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/soc/ti/k3-ringacc.h> #include <linux/soc/ti/k3-ringacc.h>
#include <net/devlink.h>
#include "am65-cpsw-qos.h" #include "am65-cpsw-qos.h"
struct am65_cpts; struct am65_cpts;
...@@ -22,6 +24,8 @@ struct am65_cpts; ...@@ -22,6 +24,8 @@ struct am65_cpts;
#define AM65_CPSW_MAX_RX_QUEUES 1 #define AM65_CPSW_MAX_RX_QUEUES 1
#define AM65_CPSW_MAX_RX_FLOWS 1 #define AM65_CPSW_MAX_RX_FLOWS 1
#define AM65_CPSW_PORT_VLAN_REG_OFFSET 0x014
struct am65_cpsw_slave_data { struct am65_cpsw_slave_data {
bool mac_only; bool mac_only;
struct cpsw_sl *mac_sl; struct cpsw_sl *mac_sl;
...@@ -32,6 +36,7 @@ struct am65_cpsw_slave_data { ...@@ -32,6 +36,7 @@ struct am65_cpsw_slave_data {
bool rx_pause; bool rx_pause;
bool tx_pause; bool tx_pause;
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];
int port_vlan;
}; };
struct am65_cpsw_port { struct am65_cpsw_port {
...@@ -47,6 +52,7 @@ struct am65_cpsw_port { ...@@ -47,6 +52,7 @@ struct am65_cpsw_port {
bool tx_ts_enabled; bool tx_ts_enabled;
bool rx_ts_enabled; bool rx_ts_enabled;
struct am65_cpsw_qos qos; struct am65_cpsw_qos qos;
struct devlink_port devlink_port;
}; };
struct am65_cpsw_host { struct am65_cpsw_host {
...@@ -85,6 +91,15 @@ struct am65_cpsw_pdata { ...@@ -85,6 +91,15 @@ struct am65_cpsw_pdata {
const char *ale_dev_id; const char *ale_dev_id;
}; };
enum cpsw_devlink_param_id {
AM65_CPSW_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
AM65_CPSW_DL_PARAM_SWITCH_MODE,
};
struct am65_cpsw_devlink {
struct am65_cpsw_common *common;
};
struct am65_cpsw_common { struct am65_cpsw_common {
struct device *dev; struct device *dev;
struct device *mdio_dev; struct device *mdio_dev;
...@@ -117,6 +132,14 @@ struct am65_cpsw_common { ...@@ -117,6 +132,14 @@ struct am65_cpsw_common {
bool pf_p0_rx_ptype_rrobin; bool pf_p0_rx_ptype_rrobin;
struct am65_cpts *cpts; struct am65_cpts *cpts;
int est_enabled; int est_enabled;
bool is_emac_mode;
u16 br_members;
int default_vlan;
struct devlink *devlink;
struct net_device *hw_bridge_dev;
struct notifier_block am65_cpsw_netdevice_nb;
unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN];
}; };
struct am65_cpsw_ndev_stats { struct am65_cpsw_ndev_stats {
...@@ -131,6 +154,7 @@ struct am65_cpsw_ndev_priv { ...@@ -131,6 +154,7 @@ struct am65_cpsw_ndev_priv {
u32 msg_enable; u32 msg_enable;
struct am65_cpsw_port *port; struct am65_cpsw_port *port;
struct am65_cpsw_ndev_stats __percpu *stats; struct am65_cpsw_ndev_stats __percpu *stats;
bool offload_fwd_mark;
}; };
#define am65_ndev_to_priv(ndev) \ #define am65_ndev_to_priv(ndev) \
...@@ -158,4 +182,6 @@ void am65_cpsw_nuss_set_p0_ptype(struct am65_cpsw_common *common); ...@@ -158,4 +182,6 @@ void am65_cpsw_nuss_set_p0_ptype(struct am65_cpsw_common *common);
void am65_cpsw_nuss_remove_tx_chns(struct am65_cpsw_common *common); void am65_cpsw_nuss_remove_tx_chns(struct am65_cpsw_common *common);
int am65_cpsw_nuss_update_tx_chns(struct am65_cpsw_common *common, int num_tx); int am65_cpsw_nuss_update_tx_chns(struct am65_cpsw_common *common, int num_tx);
bool am65_cpsw_port_dev_check(const struct net_device *dev);
#endif /* AM65_CPSW_NUSS_H_ */ #endif /* AM65_CPSW_NUSS_H_ */
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